Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
ProductRepository.php
Go to the documentation of this file.
1 <?php
8 namespace Magento\Catalog\Model;
9 
10 use Magento\Catalog\Api\Data\ProductExtension;
14 use Magento\Eav\Model\Entity\Attribute\Exception as AttributeException;
16 use Magento\Framework\Api\Data\ImageContentInterfaceFactory;
28 use Magento\Framework\Exception\TemporaryState\CouldNotSaveException as TemporaryCouldNotSaveException;
31 
38 {
42  protected $optionRepository;
43 
47  protected $productFactory;
48 
52  protected $instances = [];
53 
57  protected $instancesById = [];
58 
63 
68 
73 
77  protected $filterBuilder;
78 
82  protected $collectionFactory;
83 
87  protected $resourceModel;
88 
92  protected $linkInitializer;
93 
97  protected $linkTypeProvider;
98 
102  protected $storeManager;
103 
108 
112  protected $metadataService;
113 
118 
122  protected $fileSystem;
123 
127  protected $contentFactory;
128 
132  protected $imageProcessor;
133 
138 
143 
147  private $collectionProcessor;
148 
152  private $cacheLimit = 0;
153 
157  private $serializer;
158 
162  private $readExtensions;
163 
193  public function __construct(
194  ProductFactory $productFactory,
195  \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper $initializationHelper,
196  \Magento\Catalog\Api\Data\ProductSearchResultsInterfaceFactory $searchResultsFactory,
197  \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $collectionFactory,
198  \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
199  \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository,
201  \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks $linkInitializer,
202  \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider,
204  \Magento\Framework\Api\FilterBuilder $filterBuilder,
205  \Magento\Catalog\Api\ProductAttributeRepositoryInterface $metadataServiceInterface,
206  \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter,
207  \Magento\Catalog\Model\Product\Option\Converter $optionConverter,
208  \Magento\Framework\Filesystem $fileSystem,
209  ImageContentValidatorInterface $contentValidator,
210  ImageContentInterfaceFactory $contentFactory,
211  MimeTypeExtensionMap $mimeTypeExtensionMap,
213  \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor,
214  CollectionProcessorInterface $collectionProcessor = null,
215  \Magento\Framework\Serialize\Serializer\Json $serializer = null,
216  $cacheLimit = 1000,
217  ReadExtensions $readExtensions = null
218  ) {
219  $this->productFactory = $productFactory;
220  $this->collectionFactory = $collectionFactory;
221  $this->initializationHelper = $initializationHelper;
222  $this->searchResultsFactory = $searchResultsFactory;
223  $this->searchCriteriaBuilder = $searchCriteriaBuilder;
224  $this->resourceModel = $resourceModel;
225  $this->linkInitializer = $linkInitializer;
226  $this->linkTypeProvider = $linkTypeProvider;
227  $this->storeManager = $storeManager;
228  $this->attributeRepository = $attributeRepository;
229  $this->filterBuilder = $filterBuilder;
230  $this->metadataService = $metadataServiceInterface;
231  $this->extensibleDataObjectConverter = $extensibleDataObjectConverter;
232  $this->fileSystem = $fileSystem;
233  $this->contentFactory = $contentFactory;
234  $this->imageProcessor = $imageProcessor;
235  $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
236  $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor();
237  $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
238  ->get(\Magento\Framework\Serialize\Serializer\Json::class);
239  $this->cacheLimit = (int)$cacheLimit;
240  $this->readExtensions = $readExtensions ?: \Magento\Framework\App\ObjectManager::getInstance()
241  ->get(ReadExtensions::class);
242  }
243 
247  public function get($sku, $editMode = false, $storeId = null, $forceReload = false)
248  {
249  $cacheKey = $this->getCacheKey([$editMode, $storeId]);
250  $cachedProduct = $this->getProductFromLocalCache($sku, $cacheKey);
251  if ($cachedProduct === null || $forceReload) {
252  $product = $this->productFactory->create();
253 
254  $productId = $this->resourceModel->getIdBySku($sku);
255  if (!$productId) {
256  throw new NoSuchEntityException(
257  __("The product that was requested doesn't exist. Verify the product and try again.")
258  );
259  }
260  if ($editMode) {
261  $product->setData('_edit_mode', true);
262  }
263  if ($storeId !== null) {
264  $product->setData('store_id', $storeId);
265  }
266  $product->load($productId);
267  $this->cacheProduct($cacheKey, $product);
268  $cachedProduct = $product;
269  }
270 
271  return $cachedProduct;
272  }
273 
277  public function getById($productId, $editMode = false, $storeId = null, $forceReload = false)
278  {
279  $cacheKey = $this->getCacheKey([$editMode, $storeId]);
280  if (!isset($this->instancesById[$productId][$cacheKey]) || $forceReload) {
281  $product = $this->productFactory->create();
282  if ($editMode) {
283  $product->setData('_edit_mode', true);
284  }
285  if ($storeId !== null) {
286  $product->setData('store_id', $storeId);
287  }
288  $product->load($productId);
289  if (!$product->getId()) {
290  throw new NoSuchEntityException(
291  __("The product that was requested doesn't exist. Verify the product and try again.")
292  );
293  }
294  $this->cacheProduct($cacheKey, $product);
295  }
296  return $this->instancesById[$productId][$cacheKey];
297  }
298 
305  protected function getCacheKey($data)
306  {
307  $serializeData = [];
308  foreach ($data as $key => $value) {
309  if (is_object($value)) {
310  $serializeData[$key] = $value->getId();
311  } else {
312  $serializeData[$key] = $value;
313  }
314  }
315  $serializeData = $this->serializer->serialize($serializeData);
316  return sha1($serializeData);
317  }
318 
326  private function cacheProduct($cacheKey, ProductInterface $product)
327  {
328  $this->instancesById[$product->getId()][$cacheKey] = $product;
329  $this->saveProductInLocalCache($product, $cacheKey);
330 
331  if ($this->cacheLimit && count($this->instances) > $this->cacheLimit) {
332  $offset = round($this->cacheLimit / -2);
333  $this->instancesById = array_slice($this->instancesById, $offset, null, true);
334  $this->instances = array_slice($this->instances, $offset, null, true);
335  }
336  }
337 
346  protected function initializeProductData(array $productData, $createNew)
347  {
348  unset($productData['media_gallery']);
349  if ($createNew) {
350  $product = $this->productFactory->create();
351  $this->assignProductToWebsites($product);
352  } else {
353  $this->removeProductFromLocalCache($productData['sku']);
354  $product = $this->get($productData['sku']);
355  }
356 
357  foreach ($productData as $key => $value) {
358  $product->setData($key, $value);
359  }
360 
361  return $product;
362  }
363 
370  private function assignProductToWebsites(\Magento\Catalog\Model\Product $product)
371  {
372  if ($this->storeManager->getStore(true)->getCode() == \Magento\Store\Model\Store::ADMIN_CODE) {
373  $websiteIds = array_keys($this->storeManager->getWebsites());
374  } else {
375  $websiteIds = [$this->storeManager->getStore()->getWebsiteId()];
376  }
377 
378  $product->setWebsiteIds($websiteIds);
379  }
380 
391  protected function processNewMediaGalleryEntry(
392  ProductInterface $product,
393  array $newEntry
394  ) {
396  $contentDataObject = $newEntry['content'];
397 
399  $mediaConfig = $product->getMediaConfig();
400  $mediaTmpPath = $mediaConfig->getBaseTmpMediaPath();
401 
402  $relativeFilePath = $this->imageProcessor->processImageContent($mediaTmpPath, $contentDataObject);
403  $tmpFilePath = $mediaConfig->getTmpMediaShortUrl($relativeFilePath);
404 
405  if (!$product->hasGalleryAttribute()) {
406  throw new StateException(
407  __("The product that was requested doesn't exist. Verify the product and try again.")
408  );
409  }
410 
411  $imageFileUri = $this->getMediaGalleryProcessor()->addImage(
412  $product,
413  $tmpFilePath,
414  isset($newEntry['types']) ? $newEntry['types'] : [],
415  true,
416  isset($newEntry['disabled']) ? $newEntry['disabled'] : true
417  );
418  // Update additional fields that are still empty after addImage call
419  $this->getMediaGalleryProcessor()->updateImage(
420  $product,
421  $imageFileUri,
422  [
423  'label' => $newEntry['label'],
424  'position' => $newEntry['position'],
425  'disabled' => $newEntry['disabled'],
426  'media_type' => $newEntry['media_type'],
427  ]
428  );
429  return $this;
430  }
431 
440  private function processLinks(ProductInterface $product, $newLinks)
441  {
442  if ($newLinks === null) {
443  // If product links were not specified, don't do anything
444  return $this;
445  }
446 
447  // Clear all existing product links and then set the ones we want
448  $linkTypes = $this->linkTypeProvider->getLinkTypes();
449  foreach (array_keys($linkTypes) as $typeName) {
450  $this->linkInitializer->initializeLinks($product, [$typeName => []]);
451  }
452 
453  // Set each linktype info
454  if (!empty($newLinks)) {
455  $productLinks = [];
456  foreach ($newLinks as $link) {
457  $productLinks[$link->getLinkType()][] = $link;
458  }
459 
460  foreach ($productLinks as $type => $linksByType) {
461  $assignedSkuList = [];
463  foreach ($linksByType as $link) {
464  $assignedSkuList[] = $link->getLinkedProductSku();
465  }
466  $linkedProductIds = $this->resourceModel->getProductsIdsBySkus($assignedSkuList);
467 
468  $linksToInitialize = [];
469  foreach ($linksByType as $link) {
470  $linkDataArray = $this->extensibleDataObjectConverter
471  ->toNestedArray($link, [], \Magento\Catalog\Api\Data\ProductLinkInterface::class);
472  $linkedSku = $link->getLinkedProductSku();
473  if (!isset($linkedProductIds[$linkedSku])) {
474  throw new NoSuchEntityException(
475  __('The Product with the "%1" SKU doesn\'t exist.', $linkedSku)
476  );
477  }
478  $linkDataArray['product_id'] = $linkedProductIds[$linkedSku];
479  $linksToInitialize[$linkedProductIds[$linkedSku]] = $linkDataArray;
480  }
481 
482  $this->linkInitializer->initializeLinks($product, [$type => $linksToInitialize]);
483  }
484  }
485 
486  $product->setProductLinks($newLinks);
487  return $this;
488  }
489 
505  protected function processMediaGallery(ProductInterface $product, $mediaGalleryEntries)
506  {
507  $existingMediaGallery = $product->getMediaGallery('images');
508  $newEntries = [];
509  $entriesById = [];
510  if (!empty($existingMediaGallery)) {
511  foreach ($mediaGalleryEntries as $entry) {
512  if (isset($entry['value_id'])) {
513  $entriesById[$entry['value_id']] = $entry;
514  } else {
515  $newEntries[] = $entry;
516  }
517  }
518  foreach ($existingMediaGallery as $key => &$existingEntry) {
519  if (isset($entriesById[$existingEntry['value_id']])) {
520  $updatedEntry = $entriesById[$existingEntry['value_id']];
521  if ($updatedEntry['file'] === null) {
522  unset($updatedEntry['file']);
523  }
524  $existingMediaGallery[$key] = array_merge($existingEntry, $updatedEntry);
525  } else {
526  //set the removed flag
527  $existingEntry['removed'] = true;
528  }
529  }
530  $product->setData('media_gallery', ["images" => $existingMediaGallery]);
531  } else {
532  $newEntries = $mediaGalleryEntries;
533  }
534 
535  $images = (array)$product->getMediaGallery('images');
536  $images = $this->determineImageRoles($product, $images);
537 
538  $this->getMediaGalleryProcessor()->clearMediaAttribute($product, array_keys($product->getMediaAttributes()));
539 
540  foreach ($images as $image) {
541  if (!isset($image['removed']) && !empty($image['types'])) {
542  $this->getMediaGalleryProcessor()->setMediaAttribute($product, $image['types'], $image['file']);
543  }
544  }
545 
546  foreach ($newEntries as $newEntry) {
547  if (!isset($newEntry['content'])) {
548  throw new InputException(__('The image content is invalid. Verify the content and try again.'));
549  }
551  $contentDataObject = $this->contentFactory->create()
552  ->setName($newEntry['content']['data'][ImageContentInterface::NAME])
553  ->setBase64EncodedData($newEntry['content']['data'][ImageContentInterface::BASE64_ENCODED_DATA])
554  ->setType($newEntry['content']['data'][ImageContentInterface::TYPE]);
555  $newEntry['content'] = $contentDataObject;
556  $this->processNewMediaGalleryEntry($product, $newEntry);
557 
558  $finalGallery = $product->getData('media_gallery');
559  $newEntryId = key(array_diff_key($product->getData('media_gallery')['images'], $entriesById));
560  $newEntry = array_replace_recursive($newEntry, $finalGallery['images'][$newEntryId]);
561  $entriesById[$newEntryId] = $newEntry;
562  $finalGallery['images'][$newEntryId] = $newEntry;
563  $product->setData('media_gallery', $finalGallery);
564  }
565  return $this;
566  }
567 
573  public function save(ProductInterface $product, $saveOptions = false)
574  {
575  $tierPrices = $product->getData('tier_price');
576 
577  try {
578  $existingProduct = $this->get($product->getSku());
579 
580  $product->setData(
581  $this->resourceModel->getLinkField(),
582  $existingProduct->getData($this->resourceModel->getLinkField())
583  );
584  if (!$product->hasData(Product::STATUS)) {
585  $product->setStatus($existingProduct->getStatus());
586  }
587 
589  $extensionAttributes = $product->getExtensionAttributes();
590  if (empty($extensionAttributes->__toArray())) {
591  $product->setExtensionAttributes($existingProduct->getExtensionAttributes());
592  }
593  } catch (NoSuchEntityException $e) {
594  $existingProduct = null;
595  }
596 
597  $productDataArray = $this->extensibleDataObjectConverter
598  ->toNestedArray($product, [], ProductInterface::class);
599  $productDataArray = array_replace($productDataArray, $product->getData());
600  $ignoreLinksFlag = $product->getData('ignore_links_flag');
601  $productLinks = null;
602  if (!$ignoreLinksFlag && $ignoreLinksFlag !== null) {
603  $productLinks = $product->getProductLinks();
604  }
605  $productDataArray['store_id'] = (int)$this->storeManager->getStore()->getId();
606  $product = $this->initializeProductData($productDataArray, empty($existingProduct));
607 
608  $this->processLinks($product, $productLinks);
609  if (isset($productDataArray['media_gallery'])) {
610  $this->processMediaGallery($product, $productDataArray['media_gallery']['images']);
611  }
612 
613  if (!$product->getOptionsReadonly()) {
614  $product->setCanSaveCustomOptions(true);
615  }
616 
617  $validationResult = $this->resourceModel->validate($product);
618  if (true !== $validationResult) {
619  throw new \Magento\Framework\Exception\CouldNotSaveException(
620  __('Invalid product data: %1', implode(',', $validationResult))
621  );
622  }
623 
624  if ($tierPrices !== null) {
625  $product->setData('tier_price', $tierPrices);
626  }
627 
628  $this->saveProduct($product);
629  $this->removeProductFromLocalCache($product->getSku());
630  unset($this->instancesById[$product->getId()]);
631 
632  return $this->get($product->getSku(), false, $product->getStoreId());
633  }
634 
638  public function delete(ProductInterface $product)
639  {
640  $sku = $product->getSku();
641  $productId = $product->getId();
642  try {
643  $this->removeProductFromLocalCache($product->getSku());
644  unset($this->instancesById[$product->getId()]);
645  $this->resourceModel->delete($product);
646  } catch (ValidatorException $e) {
647  throw new CouldNotSaveException(__($e->getMessage()));
648  } catch (\Exception $e) {
649  throw new \Magento\Framework\Exception\StateException(
650  __('The "%1" product couldn\'t be removed.', $sku)
651  );
652  }
653  $this->removeProductFromLocalCache($sku);
654  unset($this->instancesById[$productId]);
655 
656  return true;
657  }
658 
662  public function deleteById($sku)
663  {
664  $product = $this->get($sku);
665  return $this->delete($product);
666  }
667 
671  public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
672  {
674  $collection = $this->collectionFactory->create();
675  $this->extensionAttributesJoinProcessor->process($collection);
676 
677  $collection->addAttributeToSelect('*');
678  $collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
679  $collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');
680 
681  $this->collectionProcessor->process($searchCriteria, $collection);
682 
683  $collection->load();
684 
685  $collection->addCategoryIds();
686  $this->addExtensionAttributes($collection);
687  $searchResult = $this->searchResultsFactory->create();
688  $searchResult->setSearchCriteria($searchCriteria);
689  $searchResult->setItems($collection->getItems());
690  $searchResult->setTotalCount($collection->getSize());
691 
692  foreach ($collection->getItems() as $product) {
693  $this->cacheProduct(
694  $this->getCacheKey(
695  [
696  false,
697  $product->getStoreId()
698  ]
699  ),
700  $product
701  );
702  }
703 
704  return $searchResult;
705  }
706 
713  private function addExtensionAttributes(Collection $collection) : Collection
714  {
715  foreach ($collection->getItems() as $item) {
716  $this->readExtensions->execute($item);
717  }
718  return $collection;
719  }
720 
729  protected function addFilterGroupToCollection(
730  \Magento\Framework\Api\Search\FilterGroup $filterGroup,
732  ) {
733  $fields = [];
734  $categoryFilter = [];
735  foreach ($filterGroup->getFilters() as $filter) {
736  $conditionType = $filter->getConditionType() ?: 'eq';
737 
738  if ($filter->getField() == 'category_id') {
739  $categoryFilter[$conditionType][] = $filter->getValue();
740  continue;
741  }
742  $fields[] = ['attribute' => $filter->getField(), $conditionType => $filter->getValue()];
743  }
744 
745  if ($categoryFilter) {
746  $collection->addCategoriesFilter($categoryFilter);
747  }
748 
749  if ($fields) {
750  $collection->addFieldToFilter($fields);
751  }
752  }
753 
759  public function cleanCache()
760  {
761  $this->instances = null;
762  $this->instancesById = null;
763  }
764 
772  private function determineImageRoles(ProductInterface $product, array $images) : array
773  {
774  $imagesWithRoles = [];
775  foreach ($images as $image) {
776  if (!isset($image['types'])) {
777  $image['types'] = [];
778  if (isset($image['file'])) {
779  foreach (array_keys($product->getMediaAttributes()) as $attribute) {
780  if ($image['file'] == $product->getData($attribute)) {
781  $image['types'][] = $attribute;
782  }
783  }
784  }
785  }
786  $imagesWithRoles[] = $image;
787  }
788  return $imagesWithRoles;
789  }
790 
796  private function getMediaGalleryProcessor()
797  {
798  if (null === $this->mediaGalleryProcessor) {
799  $this->mediaGalleryProcessor = \Magento\Framework\App\ObjectManager::getInstance()
800  ->get(\Magento\Catalog\Model\Product\Gallery\Processor::class);
801  }
803  }
804 
811  private function getCollectionProcessor()
812  {
813  if (!$this->collectionProcessor) {
814  $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get(
815  'Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor'
816  );
817  }
818  return $this->collectionProcessor;
819  }
820 
828  private function getProductFromLocalCache(string $sku, string $cacheKey)
829  {
830  $preparedSku = $this->prepareSku($sku);
831 
832  return $this->instances[$preparedSku][$cacheKey] ?? null;
833  }
834 
841  private function removeProductFromLocalCache(string $sku) :void
842  {
843  $preparedSku = $this->prepareSku($sku);
844  unset($this->instances[$preparedSku]);
845  }
846 
854  private function saveProductInLocalCache(Product $product, string $cacheKey) : void
855  {
856  $preparedSku = $this->prepareSku($product->getSku());
857  $this->instances[$preparedSku][$cacheKey] = $product;
858  }
859 
866  private function prepareSku(string $sku): string
867  {
868  return mb_strtolower(trim($sku));
869  }
870 
880  private function saveProduct($product): void
881  {
882  try {
883  $this->removeProductFromLocalCache($product->getSku());
884  unset($this->instancesById[$product->getId()]);
885  $this->resourceModel->save($product);
886  } catch (ConnectionException $exception) {
887  throw new TemporaryCouldNotSaveException(
888  __('Database connection error'),
889  $exception,
890  $exception->getCode()
891  );
892  } catch (DeadlockException $exception) {
893  throw new TemporaryCouldNotSaveException(
894  __('Database deadlock found when trying to get lock'),
895  $exception,
896  $exception->getCode()
897  );
898  } catch (LockWaitException $exception) {
899  throw new TemporaryCouldNotSaveException(
900  __('Database lock wait timeout exceeded'),
901  $exception,
902  $exception->getCode()
903  );
904  } catch (AttributeException $exception) {
906  $exception->getAttributeCode(),
907  $product->getData($exception->getAttributeCode()),
908  $exception
909  );
910  } catch (ValidatorException $e) {
911  throw new CouldNotSaveException(__($e->getMessage()));
912  } catch (LocalizedException $e) {
913  throw $e;
914  } catch (\Exception $e) {
915  throw new CouldNotSaveException(
916  __('The product was unable to be saved. Please try again.'),
917  $e
918  );
919  }
920  }
921 }
initializeProductData(array $productData, $createNew)
static invalidFieldValue($fieldName, $fieldValue, \Exception $cause=null)
$fields
Definition: details.phtml:14
__()
Definition: __.php:13
addFilterGroupToCollection(\Magento\Framework\Api\Search\FilterGroup $filterGroup, Collection $collection)
$searchCriteria
$type
Definition: item.phtml:13
$value
Definition: gender.phtml:16
getById($productId, $editMode=false, $storeId=null, $forceReload=false)
$extensionAttributes
Definition: payment.php:22
$newLinks
save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveOptions=false)
$productData
__construct(ProductFactory $productFactory, \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper $initializationHelper, \Magento\Catalog\Api\Data\ProductSearchResultsInterfaceFactory $searchResultsFactory, \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $collectionFactory, \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder, \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository, \Magento\Catalog\Model\ResourceModel\Product $resourceModel, \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks $linkInitializer, \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Api\FilterBuilder $filterBuilder, \Magento\Catalog\Api\ProductAttributeRepositoryInterface $metadataServiceInterface, \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter, \Magento\Catalog\Model\Product\Option\Converter $optionConverter, \Magento\Framework\Filesystem $fileSystem, ImageContentValidatorInterface $contentValidator, ImageContentInterfaceFactory $contentFactory, MimeTypeExtensionMap $mimeTypeExtensionMap, ImageProcessorInterface $imageProcessor, \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor, CollectionProcessorInterface $collectionProcessor=null, \Magento\Framework\Serialize\Serializer\Json $serializer=null, $cacheLimit=1000, ReadExtensions $readExtensions=null)
getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
$mediaConfig