Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
CustomerRepository.php
Go to the documentation of this file.
1 <?php
8 
17 use Magento\Customer\Model\Delegation\Storage as DelegatedStorage;
19 
26 {
30  protected $customerFactory;
31 
36 
40  protected $customerRegistry;
41 
45  protected $addressRepository;
46 
51 
55  protected $customerMetadata;
56 
61 
65  protected $eventManager;
66 
70  protected $storeManager;
71 
76 
80  protected $dataObjectHelper;
81 
85  protected $imageProcessor;
86 
91 
95  private $collectionProcessor;
96 
100  private $notificationStorage;
101 
105  private $delegatedStorage;
106 
126  public function __construct(
127  \Magento\Customer\Model\CustomerFactory $customerFactory,
128  \Magento\Customer\Model\Data\CustomerSecureFactory $customerSecureFactory,
133  \Magento\Customer\Api\Data\CustomerSearchResultsInterfaceFactory $searchResultsFactory,
134  \Magento\Framework\Event\ManagerInterface $eventManager,
139  \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor,
140  CollectionProcessorInterface $collectionProcessor,
141  NotificationStorage $notificationStorage,
142  DelegatedStorage $delegatedStorage = null
143  ) {
144  $this->customerFactory = $customerFactory;
145  $this->customerSecureFactory = $customerSecureFactory;
146  $this->customerRegistry = $customerRegistry;
147  $this->addressRepository = $addressRepository;
148  $this->customerResourceModel = $customerResourceModel;
149  $this->customerMetadata = $customerMetadata;
150  $this->searchResultsFactory = $searchResultsFactory;
151  $this->eventManager = $eventManager;
152  $this->storeManager = $storeManager;
153  $this->extensibleDataObjectConverter = $extensibleDataObjectConverter;
154  $this->dataObjectHelper = $dataObjectHelper;
155  $this->imageProcessor = $imageProcessor;
156  $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
157  $this->collectionProcessor = $collectionProcessor;
158  $this->notificationStorage = $notificationStorage;
159  $this->delegatedStorage = $delegatedStorage
160  ?? ObjectManager::getInstance()->get(DelegatedStorage::class);
161  }
162 
168  public function save(CustomerInterface $customer, $passwordHash = null)
169  {
171  $delegatedNewOperation = !$customer->getId() ? $this->delegatedStorage->consumeNewOperation() : null;
172  $prevCustomerData = null;
173  $prevCustomerDataArr = null;
174  if ($customer->getId()) {
175  $prevCustomerData = $this->getById($customer->getId());
176  $prevCustomerDataArr = $prevCustomerData->__toArray();
177  }
179  $customerArr = $customer->__toArray();
180  $customer = $this->imageProcessor->save(
181  $customer,
183  $prevCustomerData
184  );
185  $origAddresses = $customer->getAddresses();
186  $customer->setAddresses([]);
187  $customerData = $this->extensibleDataObjectConverter->toNestedArray($customer, [], CustomerInterface::class);
188  $customer->setAddresses($origAddresses);
190  $customerModel = $this->customerFactory->create(['data' => $customerData]);
191  //Model's actual ID field maybe different than "id" so "id" field from $customerData may be ignored.
192  $customerModel->setId($customer->getId());
193  $storeId = $customerModel->getStoreId();
194  if ($storeId === null) {
195  $customerModel->setStoreId($this->storeManager->getStore()->getId());
196  }
197  // Need to use attribute set or future updates can cause data loss
198  if (!$customerModel->getAttributeSetId()) {
199  $customerModel->setAttributeSetId(CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER);
200  }
201  $this->populateCustomerWithSecureData($customerModel, $passwordHash);
202  // If customer email was changed, reset RpToken info
203  if ($prevCustomerData && $prevCustomerData->getEmail() !== $customerModel->getEmail()) {
204  $customerModel->setRpToken(null);
205  $customerModel->setRpTokenCreatedAt(null);
206  }
207  if (!array_key_exists('default_billing', $customerArr)
208  && null !== $prevCustomerDataArr
209  && array_key_exists('default_billing', $prevCustomerDataArr)
210  ) {
211  $customerModel->setDefaultBilling($prevCustomerDataArr['default_billing']);
212  }
213  if (!array_key_exists('default_shipping', $customerArr)
214  && null !== $prevCustomerDataArr
215  && array_key_exists('default_shipping', $prevCustomerDataArr)
216  ) {
217  $customerModel->setDefaultShipping($prevCustomerDataArr['default_shipping']);
218  }
219  $customerModel->save();
220  $this->customerRegistry->push($customerModel);
221  $customerId = $customerModel->getId();
222  if (!$customer->getAddresses()
223  && $delegatedNewOperation
224  && $delegatedNewOperation->getCustomer()->getAddresses()
225  ) {
226  $customer->setAddresses($delegatedNewOperation->getCustomer()->getAddresses());
227  }
228  if ($customer->getAddresses() !== null) {
229  if ($customer->getId()) {
230  $existingAddresses = $this->getById($customer->getId())->getAddresses();
231  $getIdFunc = function ($address) {
232  return $address->getId();
233  };
234  $existingAddressIds = array_map($getIdFunc, $existingAddresses);
235  } else {
236  $existingAddressIds = [];
237  }
238  $savedAddressIds = [];
239  foreach ($customer->getAddresses() as $address) {
240  $address->setCustomerId($customerId)
241  ->setRegion($address->getRegion());
242  $this->addressRepository->save($address);
243  if ($address->getId()) {
244  $savedAddressIds[] = $address->getId();
245  }
246  }
247  $addressIdsToDelete = array_diff($existingAddressIds, $savedAddressIds);
248  foreach ($addressIdsToDelete as $addressId) {
249  $this->addressRepository->deleteById($addressId);
250  }
251  }
252  $this->customerRegistry->remove($customerId);
253  $savedCustomer = $this->get($customer->getEmail(), $customer->getWebsiteId());
254  $this->eventManager->dispatch(
255  'customer_save_after_data_object',
256  [
257  'customer_data_object' => $savedCustomer,
258  'orig_customer_data_object' => $prevCustomerData,
259  'delegate_data' => $delegatedNewOperation ? $delegatedNewOperation->getAdditionalData() : [],
260  ]
261  );
262 
263  return $savedCustomer;
264  }
265 
274  private function populateCustomerWithSecureData($customerModel, $passwordHash = null)
275  {
276  if ($customerModel->getId()) {
277  $customerSecure = $this->customerRegistry->retrieveSecureData($customerModel->getId());
278 
279  $customerModel->setRpToken($passwordHash ? null : $customerSecure->getRpToken());
280  $customerModel->setRpTokenCreatedAt($passwordHash ? null : $customerSecure->getRpTokenCreatedAt());
281  $customerModel->setPasswordHash($passwordHash ?: $customerSecure->getPasswordHash());
282 
283  $customerModel->setFailuresNum($customerSecure->getFailuresNum());
284  $customerModel->setFirstFailure($customerSecure->getFirstFailure());
285  $customerModel->setLockExpires($customerSecure->getLockExpires());
286  } elseif ($passwordHash) {
287  $customerModel->setPasswordHash($passwordHash);
288  }
289 
290  if ($passwordHash && $customerModel->getId()) {
291  $this->customerRegistry->remove($customerModel->getId());
292  }
293  }
294 
298  public function get($email, $websiteId = null)
299  {
300  $customerModel = $this->customerRegistry->retrieveByEmail($email, $websiteId);
301  return $customerModel->getDataModel();
302  }
303 
307  public function getById($customerId)
308  {
309  $customerModel = $this->customerRegistry->retrieve($customerId);
310  return $customerModel->getDataModel();
311  }
312 
317  {
318  $searchResults = $this->searchResultsFactory->create();
319  $searchResults->setSearchCriteria($searchCriteria);
321  $collection = $this->customerFactory->create()->getCollection();
322  $this->extensionAttributesJoinProcessor->process(
323  $collection,
324  CustomerInterface::class
325  );
326  // This is needed to make sure all the attributes are properly loaded
327  foreach ($this->customerMetadata->getAllAttributesMetadata() as $metadata) {
328  $collection->addAttributeToSelect($metadata->getAttributeCode());
329  }
330  // Needed to enable filtering on name as a whole
331  $collection->addNameToSelect();
332  // Needed to enable filtering based on billing address attributes
333  $collection->joinAttribute('billing_postcode', 'customer_address/postcode', 'default_billing', null, 'left')
334  ->joinAttribute('billing_city', 'customer_address/city', 'default_billing', null, 'left')
335  ->joinAttribute('billing_telephone', 'customer_address/telephone', 'default_billing', null, 'left')
336  ->joinAttribute('billing_region', 'customer_address/region', 'default_billing', null, 'left')
337  ->joinAttribute('billing_country_id', 'customer_address/country_id', 'default_billing', null, 'left')
338  ->joinAttribute('company', 'customer_address/company', 'default_billing', null, 'left');
339 
340  $this->collectionProcessor->process($searchCriteria, $collection);
341 
342  $searchResults->setTotalCount($collection->getSize());
343 
344  $customers = [];
346  foreach ($collection as $customerModel) {
347  $customers[] = $customerModel->getDataModel();
348  }
349  $searchResults->setItems($customers);
350  return $searchResults;
351  }
352 
356  public function delete(CustomerInterface $customer)
357  {
358  return $this->deleteById($customer->getId());
359  }
360 
364  public function deleteById($customerId)
365  {
366  $customerModel = $this->customerRegistry->retrieve($customerId);
367  $customerModel->delete();
368  $this->customerRegistry->remove($customerId);
369  $this->notificationStorage->remove(NotificationStorage::UPDATE_CUSTOMER_SESSION, $customerId);
370 
371  return true;
372  }
373 
383  protected function addFilterGroupToCollection(
384  \Magento\Framework\Api\Search\FilterGroup $filterGroup,
386  ) {
387  $fields = [];
388  foreach ($filterGroup->getFilters() as $filter) {
389  $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq';
390  $fields[] = ['attribute' => $filter->getField(), $condition => $filter->getValue()];
391  }
392  if ($fields) {
393  $collection->addFieldToFilter($fields);
394  }
395  }
396 }
$customerData
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
$customer
Definition: customers.php:11
$email
Definition: details.phtml:13
$fields
Definition: details.phtml:14
$searchCriteria
$address
Definition: customer.php:38
__construct(\Magento\Customer\Model\CustomerFactory $customerFactory, \Magento\Customer\Model\Data\CustomerSecureFactory $customerSecureFactory, \Magento\Customer\Model\CustomerRegistry $customerRegistry, \Magento\Customer\Model\ResourceModel\AddressRepository $addressRepository, \Magento\Customer\Model\ResourceModel\Customer $customerResourceModel, \Magento\Customer\Api\CustomerMetadataInterface $customerMetadata, \Magento\Customer\Api\Data\CustomerSearchResultsInterfaceFactory $searchResultsFactory, \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter, DataObjectHelper $dataObjectHelper, ImageProcessorInterface $imageProcessor, \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor, CollectionProcessorInterface $collectionProcessor, NotificationStorage $notificationStorage, DelegatedStorage $delegatedStorage=null)
save(\Magento\Customer\Api\Data\CustomerInterface $customer, $passwordHash=null)
getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
addFilterGroupToCollection(\Magento\Framework\Api\Search\FilterGroup $filterGroup, \Magento\Customer\Model\ResourceModel\Customer\Collection $collection)