This repository has been archived on 2026-07-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
espocrm-base/application/Espo/Services/Import.php
T
2019-04-25 12:14:42 +03:00

920 lines
32 KiB
PHP

<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2019 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Services;
use \Espo\Core\Exceptions\Forbidden;
use \Espo\Core\Exceptions\NotFound;
use \Espo\Core\Exceptions\Error;
use \Espo\Core\Exceptions\BadRequest;
use Espo\ORM\Entity;
class Import extends \Espo\Services\Record
{
const REVERT_PERMANENTLY_REMOVE_PERIOD_DAYS = 2;
protected function init()
{
parent::init();
$this->addDependency('serviceFactory');
$this->addDependency('fileManager');
$this->addDependency('selectManagerFactory');
$this->addDependency('fileStorageManager');
}
protected $dateFormatsMap = [
'YYYY-MM-DD' => 'Y-m-d',
'DD-MM-YYYY' => 'd-m-Y',
'MM-DD-YYYY' => 'm-d-Y',
'MM/DD/YYYY' => 'm/d/Y',
'DD/MM/YYYY' => 'd/m/Y',
'DD.MM.YYYY' => 'd.m.Y',
'MM.DD.YYYY' => 'm.d.Y',
'YYYY.MM.DD' => 'Y.m.d',
];
protected $timeFormatsMap = [
'HH:mm' => 'H:i',
'HH:mm:ss' => 'H:i:s',
'hh:mm a' => 'h:i a',
'hh:mma' => 'h:ia',
'hh:mm A' => 'h:iA',
'hh:mmA' => 'h:iA',
];
protected $services = [];
protected function getSelectManagerFactory()
{
return $this->injections['selectManagerFactory'];
}
protected function getFileStorageManager()
{
return $this->injections['fileStorageManager'];
}
protected function getFileManager()
{
return $this->injections['fileManager'];
}
protected function getAcl()
{
return $this->injections['acl'];
}
protected function getMetadata()
{
return $this->injections['metadata'];
}
protected function getServiceFactory()
{
return $this->injections['serviceFactory'];
}
public function loadAdditionalFields(Entity $entity)
{
parent::loadAdditionalFields($entity);
$importedCount = $this->getRepository()->countRelated($entity, 'imported');
$duplicateCount = $this->getRepository()->countRelated($entity, 'duplicates');
$updatedCount = $this->getRepository()->countRelated($entity, 'updated');
$entity->set([
'importedCount' => $importedCount,
'duplicateCount' => $duplicateCount,
'updatedCount' => $updatedCount
]);
}
public function findLinked($id, $link, $params)
{
$entity = $this->getRepository()->get($id);
$foreignEntityType = $entity->get('entityType');
if (!$this->getAcl()->check($entity, 'read')) {
throw new Forbidden();
}
if (!$this->getAcl()->check($foreignEntityType, 'read')) {
throw new Forbidden();
}
$selectParams = $this->getSelectManager($foreignEntityType)->getSelectParams($params, true);
if (array_key_exists($link, $this->linkSelectParams)) {
$selectParams = array_merge($selectParams, $this->linkSelectParams[$link]);
}
$collection = $this->getRepository()->findRelated($entity, $link, $selectParams);
$recordService = $this->getRecordService($foreignEntityType);
foreach ($collection as $e) {
$recordService->loadAdditionalFieldsForList($e);
$recordService->prepareEntityForOutput($e);
}
$total = $this->getRepository()->countRelated($entity, $link, $selectParams);
return [
'total' => $total,
'collection' => $collection
];
}
protected function readCsvString(&$string, $CSV_SEPARATOR = ';', $CSV_ENCLOSURE = '"', $CSV_LINEBREAK = "\n")
{
$o = [];
$cnt = strlen($string);
$esc = false;
$escesc = false;
$num = 0;
$i = 0;
while ($i < $cnt) {
$s = $string[$i];
if ($s == $CSV_LINEBREAK) {
if ($esc) {
$o[$num].= $s;
}
else {
$i++;
break;
}
}
elseif ($s == $CSV_SEPARATOR) {
if ($esc) {
$o[$num].= $s;
}
else {
$num++;
$esc = false;
$escesc = false;
}
}
elseif ($s == $CSV_ENCLOSURE) {
if ($escesc) {
$o[$num].= $CSV_ENCLOSURE;
$escesc = false;
}
if ($esc) {
$esc = false;
$escesc = true;
}
else {
$esc = true;
$escesc = false;
}
}
else {
if (!array_key_exists($num, $o)) {
$o[$num] = '';
}
if ($escesc) {
$o[$num] .= $CSV_ENCLOSURE;
$escesc = false;
}
$o[$num] .= $s;
}
$i++;
}
$string = substr($string, $i);
return $o;
}
public function revert($id)
{
$import = $this->getEntityManager()->getEntity('Import', $id);
if (empty($import)) {
throw new NotFound();
}
if (!$this->getAcl()->check($import, 'delete')) {
throw new Forbidden();
}
$pdo = $this->getEntityManager()->getPDO();
$sql = "SELECT * FROM import_entity WHERE import_id = ".$pdo->quote($import->id) . " AND is_imported = 1";
$removeFromDb = false;
$createdAt = $import->get('createdAt');
if ($createdAt) {
$dtNow = new \DateTime();
$createdAtDt = new \DateTime($createdAt);
$dayDiff = ($dtNow->getTimestamp() - $createdAtDt->getTimestamp()) / 60 / 60 / 24;
if ($dayDiff < self::REVERT_PERMANENTLY_REMOVE_PERIOD_DAYS) {
$removeFromDb = true;
}
}
$sth = $pdo->prepare($sql);
$sth->execute();
while ($row = $sth->fetch(\PDO::FETCH_ASSOC)) {
if (empty($row['entity_type']) || empty($row['entity_id'])) {
continue;
}
$entityType = $row['entity_type'];
$entityId = $row['entity_id'];
$entity = $this->getEntityManager()->getEntity($entityType, $entityId);
if ($entity) {
$this->getEntityManager()->removeEntity($entity, [
'noStream' => true,
'noNotifications' => true,
'import' => true
]);
}
if ($removeFromDb) {
$this->getEntityManager()->getRepository($entityType)->deleteFromDb($entityId);
}
}
$this->getEntityManager()->removeEntity($import);
$this->processActionHistoryRecord('delete', $import);
return true;
}
public function removeDuplicates($id)
{
$import = $this->getEntityManager()->getEntity('Import', $id);
if (empty($import)) {
throw new NotFound();
}
if (!$this->getAcl()->check($import, 'delete')) {
throw new Forbidden();
}
$pdo = $this->getEntityManager()->getPDO();
$sql = "SELECT * FROM import_entity WHERE import_id = ".$pdo->quote($import->id) . " AND is_duplicate = 1";
$sth = $pdo->prepare($sql);
$sth->execute();
while ($row = $sth->fetch(\PDO::FETCH_ASSOC)) {
if (empty($row['entity_type']) || empty($row['entity_id'])) {
continue;
}
$entityType = $row['entity_type'];
$entityId = $row['entity_id'];
$entity = $this->getEntityManager()->getEntity($entityType, $entityId);
if ($entity) {
$this->getEntityManager()->removeEntity($entity);
}
$this->getEntityManager()->getRepository($entity->getEntityType())->deleteFromDb($entityId);
}
return true;
}
public function jobRunIdleImport($data)
{
if (
empty($data->userId) ||
empty($data->userId) ||
!isset($data->importAttributeList) ||
!isset($data->params) ||
!isset($data->entityType)
) {
throw new Error("Import: Bad job data.");
}
$entityType = $data->entityType;
$params = json_decode(json_encode($data->params), true);
$attachmentId = $data->attachmentId;
$importId = $data->importId;
$importAttributeList = $data->importAttributeList;
$userId = $data->userId;
$user = $this->getEntityManager()->getEntity('User', $userId);
if (!$user) {
throw new Error("Import: User not found.");
}
if (!$user->get('isActive')) {
throw new Error("Import: User is not active.");
}
$this->import($entityType, $importAttributeList, $attachmentId, $params, $importId, $user);
}
public function import($scope, array $importAttributeList, $attachmentId, array $params = [], $importId = null, $user = null)
{
$delimiter = ',';
if (!empty($params['delimiter'])) {
$delimiter = $params['delimiter'];
}
$enclosure = '"';
if (!empty($params['textQualifier'])) {
$enclosure = $params['textQualifier'];
}
if (!$user) {
$user = $this->getUser();
}
if (!$user->isAdmin()) {
$forbiddenAttrbuteList = $this->getAclManager()->getScopeForbiddenAttributeList($user, $scope, 'edit');
foreach ($importAttributeList as $i => $attribute) {
if (in_array($attribute, $forbiddenAttrbuteList)) {
unset($importAttributeList[$i]);
}
}
if (!$this->getAclManager()->checkScope($user, $scope, 'create')) {
throw new Error('Import: Create is forbidden.');
}
}
$attachment = $this->getEntityManager()->getEntity('Attachment', $attachmentId);
if (!$attachment) {
throw new Error('Import error');
}
$contents = $this->getFileStorageManager()->getContents($attachment);
if (empty($contents)) {
throw new Error('Import error');
}
if ($importId) {
$import = $this->getEntityManager()->getEntity('Import', $importId);
if (!$import) {
throw new Error('Import: Could not find import record.');
}
} else {
$import = $this->getEntityManager()->getEntity('Import');
$import->set([
'entityType' => $scope,
'fileId' => $attachmentId
]);
$import->set('status', 'In Process');
}
$this->getEntityManager()->saveEntity($import);
$this->processActionHistoryRecord('create', $import);
if (!empty($params['idleMode'])) {
$params['idleMode'] = false;
$job = $this->getEntityManager()->getEntity('Job');
$job->set([
'serviceName' => 'Import',
'methodName' => 'jobRunIdleImport',
'data' => [
'entityType' => $scope,
'params' => $params,
'attachmentId' => $attachmentId,
'importAttributeList' => $importAttributeList,
'importId' => $import->id,
'userId' => $this->getUser()->id
]
]);
$this->getEntityManager()->saveEntity($job);
return [
'id' => $import->id,
'countCreated' => 0,
'countUpdated' => 0
];
}
try {
$pdo = $this->getEntityManager()->getPDO();
$result = [
'importedIds' => [],
'updatedIds' => [],
'duplicateIds' => []
];
$i = -1;
$contents = str_replace("\r\n", "\n", $contents);
while ($arr = $this->readCsvString($contents, $delimiter, $enclosure)) {
$i++;
if ($i == 0 && !empty($params['headerRow'])) {
continue;
}
if (count($arr) == 1 && empty($arr[0])) {
continue;
}
$r = $this->importRow($scope, $importAttributeList, $arr, $params, $user);
if (empty($r)) {
continue;
}
if (!empty($r['isImported'])) {
$result['importedIds'][] = $r['id'];
}
if (!empty($r['isUpdated'])) {
$result['updatedIds'][] = $r['id'];
}
if (!empty($r['isDuplicate'])) {
$result['duplicateIds'][] = $r['id'];
}
$sql = "
INSERT INTO import_entity
(entity_type, entity_id, import_id, is_imported, is_updated, is_duplicate)
VALUES
(:entityType, :entityId, :importId, :isImported, :isUpdated, :isDuplicate)
";
$sth = $pdo->prepare($sql);
$sth->bindValue(':entityType', $scope);
$sth->bindValue(':entityId', $r['id']);
$sth->bindValue(':importId', $import->id);
$sth->bindValue(':isImported', !empty($r['isImported']), \PDO::PARAM_BOOL);
$sth->bindValue(':isUpdated', !empty($r['isUpdated']), \PDO::PARAM_BOOL);
$sth->bindValue(':isDuplicate', !empty($r['isDuplicate']), \PDO::PARAM_BOOL);
$sth->execute();
}
} catch (\Exception $e) {
$GLOBALS['log']->error('Import Error: '. $e->getMessage());
$import->set('status', 'Failed');
}
$import->set('status', 'Complete');
$this->getEntityManager()->saveEntity($import);
return [
'id' => $import->id,
'countCreated' => count($result['importedIds']),
'countUpdated' => count($result['updatedIds']),
];
}
public function importRow($scope, array $importAttributeList, array $row, array $params = [], $user)
{
$id = null;
$action = 'create';
if (!empty($params['action'])) {
$action = $params['action'];
}
if (empty($importAttributeList)) {
return;
}
if (in_array($action, ['createAndUpdate', 'update'])) {
$updateByAttributeList = [];
$whereClause = [];
if (!empty($params['updateBy']) && is_array($params['updateBy'])) {
foreach ($params['updateBy'] as $i) {
if (array_key_exists($i, $importAttributeList)) {
$updateByAttributeList[] = $importAttributeList[$i];
$whereClause[$importAttributeList[$i]] = $row[$i];
}
}
}
}
$recordService = $this->getRecordService($scope);
if (in_array($action, ['createAndUpdate', 'update'])) {
if (!count($updateByAttributeList)) {
return;
}
$entity = $this->getEntityManager()->getRepository($scope)->where($whereClause)->findOne();
if ($entity) {
if (!$user->isAdmin()) {
if (!$this->getAclManager()->checkEntity($user, $entity, 'edit')) {
return;
}
}
}
if (!$entity) {
if ($action == 'createAndUpdate') {
$entity = $this->getEntityManager()->getEntity($scope);
if (array_key_exists('id', $whereClause)) {
$entity->set('id', $whereClause['id']);
}
} else {
return;
}
}
} else {
$entity = $this->getEntityManager()->getEntity($scope);
}
$isNew = $entity->isNew();
if (!empty($params['defaultValues'])) {
if (is_object($params['defaultValues'])) {
$v = get_object_vars($params['defaultValues']);
} else {
$v = $params['defaultValues'];
}
$entity->set($v);
}
$attributeDefs = $entity->getAttributes();
$relDefs = $entity->getRelations();
$phoneFieldList = [];
if (
$entity->hasAttribute('phoneNumber')
&&
$entity->getAttributeParam('phoneNumber', 'fieldType') === 'phone'
) {
$typeList = $this->getMetadata()->get('entityDefs.' . $scope . '.fields.phoneNumber.typeList', []);
foreach ($typeList as $type) {
$attr = str_replace(' ', '_', ucfirst($type));
$phoneFieldList[] = 'phoneNumber' . $attr;
}
}
$valueMap = (object) [];
foreach ($importAttributeList as $i => $attribute) {
if (!empty($attribute)) {
if (!array_key_exists($i, $row)) {
continue;
}
$value = $row[$i];
$valueMap->$attribute = $value;
}
}
foreach ($importAttributeList as $i => $attribute) {
if (!empty($attribute)) {
if (!array_key_exists($i, $row)) {
continue;
}
$value = $row[$i];
if ($attribute == 'id') {
if ($params['action'] == 'create') {
$entity->id = $value;
}
continue;
}
if (array_key_exists($attribute, $attributeDefs)) {
if ($value !== '') {
$type = $this->getMetadata()->get(['entityDefs', $scope, 'fields', $attribute, 'type']);
if ($attribute === 'emailAddress' && $type === 'email') {
$emailAddressData = $entity->get('emailAddressData');
$emailAddressData = $emailAddressData ?? [];
$o = (object) [
'emailAddress' => $value,
'primary' => true,
];
$emailAddressData[] = $o;
$entity->set('emailAddressData', $emailAddressData);
continue;
}
if ($attribute === 'phoneNumber' && $type === 'phone') {
$phoneNumberData = $entity->get('phoneNumberData');
$phoneNumberData = $phoneNumberData ?? [];
$o = (object) [
'phoneNumber' => $value,
'primary' => true,
];
$phoneNumberData[] = $o;
$entity->set('phoneNumberData', $phoneNumberData);
continue;
}
if ($type == 'personName') {
$firstNameAttribute = 'first' . ucfirst($attribute);
$lastNameAttribute = 'last' . ucfirst($attribute);
$personName = $this->parsePersonName($value, $params['personNameFormat']);
if (!$entity->get($firstNameAttribute)) {
$personName['firstName'] = $this->prepareAttributeValue($entity, $firstNameAttribute, $personName['firstName']);
$entity->set($firstNameAttribute, $personName['firstName']);
}
if (!$entity->get($lastNameAttribute)) {
$personName['lastName'] = $this->prepareAttributeValue($entity, $lastNameAttribute, $personName['lastName']);
$entity->set($lastNameAttribute, $personName['lastName']);
}
continue;
}
$entity->set($attribute, $this->parseValue($entity, $attribute, $value, $params));
}
} else {
if (in_array($attribute, $phoneFieldList) && !empty($value)) {
$phoneNumberData = $entity->get('phoneNumberData');
$isPrimary = false;
if (empty($phoneNumberData)) {
$phoneNumberData = [];
if (empty($valueMap->phoneNumber)) $isPrimary = true;
}
$type = str_replace('phoneNumber', '', $attribute);
$type = str_replace('_', ' ', $type);
$o = (object) [
'phoneNumber' => $value,
'type' => $type,
'primary' => $isPrimary,
];
$phoneNumberData[] = $o;
$entity->set('phoneNumberData', $phoneNumberData);
}
if (
strpos($attribute, 'emailAddress') === 0 && $attribute !== 'emailAddress'
&&
$entity->hasAttribute('emailAddress')
&&
$entity->hasAttribute('emailAddressData')
&&
is_numeric(substr($attribute, 12))
&&
intval(substr($attribute, 12)) >= 2
&&
intval(substr($attribute, 12)) <= 4
&&
!empty($value)
) {
$emailAddressData = $entity->get('emailAddressData');
$isPrimary = false;
if (empty($emailAddressData)) {
$emailAddressData = [];
if (empty($valueMap->emailAddress)) $isPrimary = true;
}
$o = (object) [
'emailAddress' => $value,
'primary' => $isPrimary,
];
$emailAddressData[] = $o;
$entity->set('emailAddressData', $emailAddressData);
}
}
}
}
$defaultCurrency = $this->getConfig('defaultCurrency');
if (!empty($params['currency'])) {
$defaultCurrency = $params['currency'];
}
$mFieldsDefs = $this->getMetadata()->get(['entityDefs', $entity->getEntityType(), 'fields'], []);
foreach ($mFieldsDefs as $field => $defs) {
if (!empty($defs['type']) && $defs['type'] === 'currency') {
if ($entity->has($field) && !$entity->get($field . 'Currency')) {
$entity->set($field . 'Currency', $defaultCurrency);
}
}
}
foreach ($importAttributeList as $i => $attribute) {
if (!array_key_exists($attribute, $attributeDefs)) continue;;
$defs = $attributeDefs[$attribute];
$type = $attributeDefs[$attribute]['type'];
if (in_array($type, [Entity::FOREIGN, Entity::VARCHAR]) && !empty($defs['foreign'])) {
$relatedEntityIsPerson = is_array($defs['foreign']) && in_array('firstName', $defs['foreign']) && in_array('lastName', $defs['foreign']);
if ($defs['foreign'] === 'name' || $relatedEntityIsPerson) {
if ($entity->has($attribute)) {
$relation = $defs['relation'];
if ($attribute == $relation . 'Name' && !$entity->has($relation . 'Id') && array_key_exists($relation, $relDefs)) {
if ($relDefs[$relation]['type'] == Entity::BELONGS_TO) {
$value = $entity->get($attribute);
$scope = $relDefs[$relation]['entity'];
if ($relatedEntityIsPerson) {
$where = $this->parsePersonName($value, $params['personNameFormat']);
} else {
$where['name'] = $value;
}
$found = $this->getEntityManager()->getRepository($scope)->where($where)->findOne();
if ($found) {
$entity->set($relation . 'Id', $found->id);
$entity->set($relation . 'Name', $found->get('name'));
} else {
if (!in_array($scope, ['User', 'Team'])) {
// TODO create related record with name $name and relate
}
}
}
}
}
}
}
}
$result = [];
try {
if ($isNew) {
$isDuplicate = false;
if (empty($params['skipDuplicateChecking'])) {
$isDuplicate = $recordService->checkIsDuplicate($entity);
}
}
if ($entity->id) {
$sql = $this->getEntityManager()->getRepository($entity->getEntityType())->deleteFromDb($entity->id, true);
}
$saveResult = $this->getEntityManager()->saveEntity($entity, [
'noStream' => true,
'noNotifications' => true,
'import' => true,
'silent' => !empty($params['silentMode']),
]);
if ($saveResult) {
$result['id'] = $entity->id;
if ($isNew) {
$result['isImported'] = true;
if ($isDuplicate) {
$result['isDuplicate'] = true;
}
} else {
$result['isUpdated'] = true;
}
}
} catch (\Exception $e) {
$GLOBALS['log']->error('Import: [' . $e->getCode() . '] ' .$e->getMessage());
}
return $result;
}
protected function prepareAttributeValue($entity, $attribute, $value)
{
if ($entity->getAttributeType($attribute) === $entity::VARCHAR) {
$maxLength = $entity->getAttributeParam($attribute, 'len');
if ($maxLength) {
if (mb_strlen($value) > $maxLength) {
$value = substr($value, 0, $maxLength);
}
}
}
return $value;
}
protected function parsePersonName($value, $format)
{
$firstName = '';
$lastName = $value;
switch ($format) {
case 'f l':
$pos = strpos($value, ' ');
if ($pos) {
$firstName = trim(substr($value, 0, $pos));
$lastName = trim(substr($value, $pos + 1));
}
break;
case 'l f':
$pos = strpos($value, ' ');
if ($pos) {
$lastName = trim(substr($value, 0, $pos));
$firstName = trim(substr($value, $pos + 1));
}
break;
case 'l, f':
$pos = strpos($value, ',');
if ($pos) {
$lastName = trim(substr($value, 0, $pos));
$firstName = trim(substr($value, $pos + 1));
}
break;
}
return ['firstName' => $firstName, 'lastName' => $lastName];
}
protected function parseValue(Entity $entity, $attribute, $value, $params = [])
{
$decimalMark = '.';
if (!empty($params['decimalMark'])) {
$decimalMark = $params['decimalMark'];
}
$dateFormat = 'Y-m-d';
if (!empty($params['dateFormat'])) {
if (!empty($this->dateFormatsMap[$params['dateFormat']])) {
$dateFormat = $this->dateFormatsMap[$params['dateFormat']];
}
}
$timeFormat = 'H:i';
if (!empty($params['timeFormat'])) {
if (!empty($this->timeFormatsMap[$params['timeFormat']])) {
$timeFormat = $this->timeFormatsMap[$params['timeFormat']];
}
}
$type = $entity->getAttributeType($attribute);
switch ($type) {
case Entity::DATE:
$dt = \DateTime::createFromFormat($dateFormat, $value);
if ($dt) {
return $dt->format('Y-m-d');
}
return null;
break;
case Entity::DATETIME:
$timezone = new \DateTimeZone(isset($params['timezone']) ? $params['timezone'] : 'UTC');
$dt = \DateTime::createFromFormat($dateFormat . ' ' . $timeFormat, $value, $timezone);
if ($dt) {
$dt->setTimezone(new \DateTimeZone('UTC'));
return $dt->format('Y-m-d H:i:s');
}
return null;
break;
case Entity::FLOAT:
$a = explode($decimalMark, $value);
$a[0] = preg_replace('/[^A-Za-z0-9\-]/', '', $a[0]);
if (count($a) > 1) {
return floatval($a[0] . '.' . $a[1]);
} else {
return floatval($a[0]);
}
case Entity::INT:
return intval($value);
case Entity::JSON_OBJECT:
$value = \Espo\Core\Utils\Json::decode($value);
return $value;
case Entity::JSON_ARRAY:
if (!is_string($value)) return;
if (!strlen($value)) return;
if ($value[0] === '[') {
$value = \Espo\Core\Utils\Json::decode($value);
return $value;
} else {
$value = explode(',', $value);
return $value;
}
}
$value = $this->prepareAttributeValue($entity, $attribute, $value);
return $value;
}
protected function getRecordService($scope)
{
if (empty($this->services[$scope])) {
if ($this->getServiceFactory()->checkExists($scope)) {
$service = $this->getServiceFactory()->create($scope);
} else {
$service = $this->getServiceFactory()->create('Record');
$service->setEntityType($scope);
}
$this->services[$scope] = $service;
}
return $this->services[$scope];
}
public function unmarkAsDuplicate($id, $entityType, $entityId)
{
$pdo = $this->getEntityManager()->getPDO();
$sql = "
UPDATE import_entity
SET is_duplicate = 0
WHERE
import_id = ".$pdo->quote($id)." AND
entity_type = ".$pdo->quote($entityType)." AND
entity_id = ".$pdo->quote($entityId)."
";
if ($pdo->query($sql)) {
return true;
}
}
}