addDependency('user'); $this->addDependency('acl'); $this->addDependency('aclManager'); } protected function getAcl() { return $this->getInjection('acl'); } public function getIdListFormAddressList(array $addressList = []) { return $this->getIds($addressList); } public function getIds(array $addressList = []) { $ids = array(); if (!empty($addressList)) { $lowerAddressList = []; foreach ($addressList as $address) { $lowerAddressList[] = trim(strtolower($address)); } $eaCollection = $this->where([ [ 'lower' => $lowerAddressList ] ])->find(); $ids = array(); $exist = array(); foreach ($eaCollection as $ea) { $ids[] = $ea->id; $exist[] = $ea->get('lower'); } foreach ($addressList as $address) { $address = trim($address); if (empty($address) || !filter_var($address, FILTER_VALIDATE_EMAIL)) { continue; } if (!in_array(strtolower($address), $exist)) { $ea = $this->get(); $ea->set('name', $address); $this->save($ea); $ids[] = $ea->id; } } } return $ids; } public function getEmailAddressData(Entity $entity) { $data = array(); $pdo = $this->getEntityManager()->getPDO(); $sql = " SELECT email_address.name, email_address.lower, email_address.invalid, email_address.opt_out AS optOut, entity_email_address.primary FROM entity_email_address JOIN email_address ON email_address.id = entity_email_address.email_address_id AND email_address.deleted = 0 WHERE entity_email_address.entity_id = ".$pdo->quote($entity->id)." AND entity_email_address.entity_type = ".$pdo->quote($entity->getEntityName())." AND entity_email_address.deleted = 0 ORDER BY entity_email_address.primary DESC "; $sth = $pdo->prepare($sql); $sth->execute(); if ($rows = $sth->fetchAll()) { foreach ($rows as $row) { $obj = new \StdClass(); $obj->emailAddress = $row['name']; $obj->lower = $row['lower']; $obj->primary = ($row['primary'] == '1') ? true : false; $obj->optOut = ($row['optOut'] == '1') ? true : false; $obj->invalid = ($row['invalid'] == '1') ? true : false; $data[] = $obj; } } return $data; } public function getByAddress($address) { return $this->where(array('lower' => strtolower($address)))->findOne(); } public function getEntityListByAddressId($emailAddressId, $exceptionEntity = null) { $entityList = []; $pdo = $this->getEntityManager()->getPDO(); $sql = " SELECT entity_email_address.entity_type AS 'entityType', entity_email_address.entity_id AS 'entityId' FROM entity_email_address WHERE entity_email_address.email_address_id = ".$pdo->quote($emailAddressId)." AND entity_email_address.deleted = 0 "; if ($exceptionEntity) { $sql .= " AND ( entity_email_address.entity_type <> " .$pdo->quote($exceptionEntity->getEntityType()) . " OR entity_email_address.entity_id <> " .$pdo->quote($exceptionEntity->id) . " ) "; } $sth = $pdo->prepare($sql); $sth->execute(); while ($row = $sth->fetch()) { if (empty($row['entityType']) || empty($row['entityId'])) continue; if (!$this->getEntityManager()->hasRepository($row['entityType'])) continue; $entity = $this->getEntityManager()->getEntity($row['entityType'], $row['entityId']); if ($entity) { $entityList[] = $entity; } } return $entityList; } public function getEntityByAddressId($emailAddressId, $entityType = null, $onlyName = false) { $pdo = $this->getEntityManager()->getPDO(); $sql = " SELECT entity_email_address.entity_type AS 'entityType', entity_email_address.entity_id AS 'entityId' FROM entity_email_address WHERE entity_email_address.email_address_id = ".$pdo->quote($emailAddressId)." AND entity_email_address.deleted = 0 "; if ($entityType) { $sql .= " AND entity_email_address.entity_type = " . $pdo->quote($entityType) . " "; } $sql .= " ORDER BY entity_email_address.primary DESC, FIELD(entity_email_address.entity_type, 'User', 'Contact', 'Lead', 'Account') "; $sth = $pdo->prepare($sql); $sth->execute(); while ($row = $sth->fetch()) { if (!empty($row['entityType']) && !empty($row['entityId'])) { if (!$this->getEntityManager()->hasRepository($row['entityType'])) { return; } if ($onlyName) { $entity = $this->getEntityManager()->getRepository($row['entityType']) ->select(['id', 'name']) ->where(['id' => $row['entityId']]) ->findOne(); } else { $entity = $this->getEntityManager()->getEntity($row['entityType'], $row['entityId']); } if ($entity) { return $entity; } } } } public function getEntityByAddress($address, $entityType = null, $order = ['User', 'Contact', 'Lead', 'Account']) { $pdo = $this->getEntityManager()->getPDO(); $a = []; foreach ($order as $item) { $a[] = $pdo->quote($item); } $sql = " SELECT entity_email_address.entity_type AS 'entityType', entity_email_address.entity_id AS 'entityId' FROM entity_email_address JOIN email_address ON email_address.id = entity_email_address.email_address_id AND email_address.deleted = 0 WHERE email_address.lower = ".$pdo->quote(strtolower($address))." AND entity_email_address.deleted = 0 "; if ($entityType) { $sql .= " AND entity_email_address.entity_type = " . $pdo->quote($entityType) . " "; } $sql .= " ORDER BY FIELD(entity_email_address.entity_type, ".join(',', array_reverse($a)).") DESC, entity_email_address.primary DESC "; $sth = $pdo->prepare($sql); $sth->execute(); while ($row = $sth->fetch()) { if (!empty($row['entityType']) && !empty($row['entityId'])) { $entity = $this->getEntityManager()->getEntity($row['entityType'], $row['entityId']); if ($entity) { return $entity; } } } } public function storeEntityEmailAddress(Entity $entity) { $emailAddressValue = $entity->get('emailAddress'); if (is_string($emailAddressValue)) { $emailAddressValue = trim($emailAddressValue); } $emailAddressData = null; if ($entity->has('emailAddressData')) { $emailAddressData = $entity->get('emailAddressData'); } $pdo = $this->getEntityManager()->getPDO(); if ($emailAddressData !== null && is_array($emailAddressData)) { $previousEmailAddressData = array(); if (!$entity->isNew()) { $previousEmailAddressData = $this->getEmailAddressData($entity); } $hash = array(); foreach ($emailAddressData as $row) { $key = trim($row->emailAddress); if (!empty($key)) { $key = strtolower($key); $hash[$key] = [ 'primary' => !empty($row->primary) ? true : false, 'optOut' => !empty($row->optOut) ? true : false, 'invalid' => !empty($row->invalid) ? true : false, 'emailAddress' => trim($row->emailAddress) ]; } } if ( $entity->has('emailAddressIsOptedOut') && ( $entity->isNew() || ( $entity->hasFetched('emailAddressIsOptedOut') && $entity->get('emailAddressIsOptedOut') !== $entity->getFetched('emailAddressIsOptedOut') ) ) ) { if ($emailAddressValue) { $key = strtolower($emailAddressValue); if ($key && isset($hash[$key])) { $hash[$key]['optOut'] = $entity->get('emailAddressIsOptedOut'); } } } $hashPrev = array(); foreach ($previousEmailAddressData as $row) { $key = $row->lower; if (!empty($key)) { $hashPrev[$key] = array( 'primary' => $row->primary ? true : false, 'optOut' => $row->optOut ? true : false, 'invalid' => $row->invalid ? true : false, 'emailAddress' => $row->emailAddress ); } } $primary = false; $toCreate = array(); $toUpdate = array(); $toRemove = array(); $revertData = []; foreach ($hash as $key => $data) { $new = true; $changed = false; if ($hash[$key]['primary']) { $primary = $key; } if (array_key_exists($key, $hashPrev)) { $new = false; $changed = $hash[$key]['optOut'] != $hashPrev[$key]['optOut'] || $hash[$key]['invalid'] != $hashPrev[$key]['invalid'] || $hash[$key]['emailAddress'] !== $hashPrev[$key]['emailAddress']; if ($hash[$key]['primary']) { if ($hash[$key]['primary'] == $hashPrev[$key]['primary']) { $primary = false; } } } if ($new) { $toCreate[] = $key; } if ($changed) { $toUpdate[] = $key; } } foreach ($hashPrev as $key => $data) { if (!array_key_exists($key, $hash)) { $toRemove[] = $key; } } foreach ($toRemove as $address) { $emailAddress = $this->getByAddress($address); if ($emailAddress) { $query = " DELETE FROM entity_email_address WHERE entity_id = ".$pdo->quote($entity->id)." AND entity_type = ".$pdo->quote($entity->getEntityName())." AND email_address_id = ".$pdo->quote($emailAddress->id)." "; $sth = $pdo->prepare($query); $sth->execute(); } } foreach ($toUpdate as $address) { $emailAddress = $this->getByAddress($address); if ($emailAddress) { $skipSave = $this->checkChangeIsForbidden($emailAddress, $entity); if (!$skipSave) { $emailAddress->set(array( 'optOut' => $hash[$address]['optOut'], 'invalid' => $hash[$address]['invalid'], 'name' => $hash[$address]['emailAddress'] )); $this->save($emailAddress); } else { $revertData[$address] = [ 'optOut' => $emailAddress->get('optOut'), 'invalid' => $emailAddress->get('invalid') ]; } } } foreach ($toCreate as $address) { $emailAddress = $this->getByAddress($address); if (!$emailAddress) { $emailAddress = $this->get(); $emailAddress->set(array( 'name' => $hash[$address]['emailAddress'], 'optOut' => $hash[$address]['optOut'], 'invalid' => $hash[$address]['invalid'], )); $this->save($emailAddress); } else { $skipSave = $this->checkChangeIsForbidden($emailAddress, $entity); if (!$skipSave) { if ( $emailAddress->get('optOut') != $hash[$address]['optOut'] || $emailAddress->get('invalid') != $hash[$address]['invalid'] || $emailAddress->get('emailAddress') != $hash[$address]['emailAddress'] ) { $emailAddress->set(array( 'optOut' => $hash[$address]['optOut'], 'invalid' => $hash[$address]['invalid'], 'name' => $hash[$address]['emailAddress'] )); $this->save($emailAddress); } } else { $revertData[$address] = [ 'optOut' => $emailAddress->get('optOut'), 'invalid' => $emailAddress->get('invalid') ]; } } $query = " INSERT entity_email_address (entity_id, entity_type, email_address_id, `primary`) VALUES ( ".$pdo->quote($entity->id).", ".$pdo->quote($entity->getEntityName()).", ".$pdo->quote($emailAddress->id).", ".$pdo->quote((int)($address === $primary))." ) ON DUPLICATE KEY UPDATE deleted = 0, `primary` = ".$pdo->quote((int)($address === $primary))." "; $sth = $pdo->prepare($query); $sth->execute(); } if ($primary) { $emailAddress = $this->getByAddress($primary); if ($emailAddress) { $query = " UPDATE entity_email_address SET `primary` = 0 WHERE entity_id = ".$pdo->quote($entity->id)." AND entity_type = ".$pdo->quote($entity->getEntityName())." AND `primary` = 1 AND deleted = 0 "; $sth = $pdo->prepare($query); $sth->execute(); $query = " UPDATE entity_email_address SET `primary` = 1 WHERE entity_id = ".$pdo->quote($entity->id)." AND entity_type = ".$pdo->quote($entity->getEntityName())." AND email_address_id = ".$pdo->quote($emailAddress->id)." AND deleted = 0 "; $sth = $pdo->prepare($query); $sth->execute(); } } if (!empty($revertData)) { foreach ($emailAddressData as $row) { if (!empty($revertData[$row->emailAddress])) { $row->optOut = $revertData[$row->emailAddress]['optOut']; $row->invalid = $revertData[$row->emailAddress]['invalid']; } } $entity->set('emailAddressData', $emailAddressData); } } else { if (!$entity->has('emailAddress')) { return; } $entityRepository = $this->getEntityManager()->getRepository($entity->getEntityName()); if (!empty($emailAddressValue)) { if ($emailAddressValue != $entity->getFetched('emailAddress')) { $emailAddressNew = $this->where(array('lower' => strtolower($emailAddressValue)))->findOne(); $isNewEmailAddress = false; if (!$emailAddressNew) { $emailAddressNew = $this->get(); $emailAddressNew->set('name', $emailAddressValue); if ($entity->has('emailAddressIsOptedOut')) { $emailAddressNew->set('optOut', !!$entity->get('emailAddressIsOptedOut')); } $this->save($emailAddressNew); $isNewEmailAddress = true; } $emailAddressValueOld = $entity->getFetched('emailAddress'); if (!empty($emailAddressValueOld)) { $emailAddressOld = $this->getByAddress($emailAddressValueOld); if ($emailAddressOld) { $entityRepository->unrelate($entity, 'emailAddresses', $emailAddressOld); } } $entityRepository->relate($entity, 'emailAddresses', $emailAddressNew); if ($entity->has('emailAddressIsOptedOut')) { $this->markAddressOptedOut($emailAddressValue, !!$entity->get('emailAddressIsOptedOut')); } $query = " UPDATE entity_email_address SET `primary` = 1 WHERE entity_id = ".$pdo->quote($entity->id)." AND entity_type = ".$pdo->quote($entity->getEntityName())." AND email_address_id = ".$pdo->quote($emailAddressNew->id)." "; $sth = $pdo->prepare($query); $sth->execute(); } else { if ( $entity->has('emailAddressIsOptedOut') && ( $entity->isNew() || ( $entity->hasFetched('emailAddressIsOptedOut') && $entity->get('emailAddressIsOptedOut') !== $entity->getFetched('emailAddressIsOptedOut') ) ) ) { $this->markAddressOptedOut($emailAddressValue, !!$entity->get('emailAddressIsOptedOut')); } } } else { $emailAddressValueOld = $entity->getFetched('emailAddress'); if (!empty($emailAddressValueOld)) { $emailAddressOld = $this->getByAddress($emailAddressValueOld); if ($emailAddressOld) { $entityRepository->unrelate($entity, 'emailAddresses', $emailAddressOld); } } } } } protected function checkChangeIsForbidden($entity, $excludeEntity) { return !$this->getInjection('aclManager')->getImplementation('EmailAddress')->checkEditInEntity($this->getInjection('user'), $entity, $excludeEntity); } public function markAddressOptedOut($address, $isOptedOut = true) { $emailAddress = $this->getByAddress($address); if ($emailAddress) { $emailAddress->set('optOut', !!$isOptedOut); $this->save($emailAddress); } } }