/**
  * Fetch the media of the items to the target
  *
  * @param ArrayCollection $items
  * @param string          $target
  * @param string          $identifier
  */
 public function fetchAll(ArrayCollection $items, $target, $identifier)
 {
     $target = DIRECTORY_SEPARATOR !== substr($target, -1) ? $target . DIRECTORY_SEPARATOR : $target;
     foreach ($items as $value) {
         if (!$value instanceof ProductValueInterface) {
             throw new \InvalidArgumentException(sprintf('Value is not an instance of %s.', ProductValueInterface::class));
         }
         if (in_array($value->getAttribute()->getAttributeType(), $this->mediaAttributeTypes) && null !== ($media = $value->getMedia())) {
             $exportPath = $this->fileExporterPath->generate(['locale' => $value->getLocale(), 'scope' => $value->getScope()], ['identifier' => $identifier, 'code' => $value->getAttribute()->getCode()]);
             $this->fetch(['from' => $media->getKey(), 'to' => ['filePath' => $target . $exportPath, 'filename' => $media->getOriginalFilename()], 'storage' => $media->getStorage()]);
         }
     }
 }
 /**
  * - Add the media to the $this->writtenFiles to be archive later
  * - Update the value of each media in the standard format to add the final path of media in archive.
  *
  * The standard format for a media contains only the filePath (which is the unique key of the media):
  * {
  *     "values": {
  *         "picture": [
  *              {
  *                  "locale": "en_US",
  *                  "scope": "ecommerce",
  *                  "data": [
  *                      "filePath": "a/b/c/d/e/it_s_my_filename.jpg"
  *                  ]
  *              }
  *          ]
  *     }
  * }
  *
  * In exported files, we don't want to see the key, but the original filename. As the standard format does not
  * contain this information, we use the Finder() to find the media in the temporary directory created in processor.
  *
  * After:
  * {
  *     "values": {
  *         "picture": [
  *              {
  *                  "locale": "en_US",
  *                  "scope": "ecommerce",
  *                  "data": [
  *                      "filePath": "files/item_identifier/picture/en_US/ecommerce/it's my filename.jpg"
  *                  ]
  *              }
  *          ]
  *     }
  * }
  *
  * @param array  $item          standard format of an item
  * @param string $tmpDirectory  directory where media have been copied before to be exported
  *
  * @return array
  */
 protected function resolveMediaPaths(array $item, $tmpDirectory)
 {
     $attributeTypes = $this->attributeRepository->getAttributeTypeByCodes(array_keys($item['values']));
     $mediaAttributeTypes = array_filter($attributeTypes, function ($attributeCode) {
         return in_array($attributeCode, $this->mediaAttributeTypes);
     });
     $identifier = $this->getItemIdentifier($item);
     foreach ($mediaAttributeTypes as $attributeCode => $attributeType) {
         foreach ($item['values'][$attributeCode] as $index => $value) {
             if (null !== $value['data']) {
                 $exportDirectory = $this->fileExporterPath->generate($value, ['identifier' => $identifier, 'code' => $attributeCode]);
                 $finder = new Finder();
                 if (is_dir($tmpDirectory . $exportDirectory)) {
                     $files = iterator_to_array($finder->files()->in($tmpDirectory . $exportDirectory));
                     if (!empty($files)) {
                         $path = $exportDirectory . current($files)->getFilename();
                         $this->writtenFiles[$tmpDirectory . $path] = $path;
                         $item['values'][$attributeCode][$index]['data']['filePath'] = $path;
                     }
                 }
             }
         }
     }
     return $item;
 }
 /**
  * {@inheritdoc}
  */
 protected function doNormalize($file, $format = null, array $context = [])
 {
     /**
      * "prepare_copy" is used for medias export
      *      [
      *          'storageAlias' => 'my_file_storage',
      *          'filePath' => '9/4/0/c/940cce20eaaef7fb622f1f9f4f8a0e3e11271d86_SNKRS_1R.png'
      *          'exportPath' => 'files/SNKRS-1B/side_view/akene-mobile.jpg'
      *      ]
      */
     if (isset($context['prepare_copy']) && true === $context['prepare_copy'] && isset($context['value'])) {
         $identifier = isset($context['identifier']) ? $context['identifier'] : null;
         return ['storageAlias' => $file->getStorage(), 'filePath' => $file->getKey(), 'exportPath' => $this->pathGenerator->generate($context['value'], ['identifier' => $identifier])];
     }
     /**
      * "versioning" is used for versioning
      *      [
      *          'media' => '9/4/0/c/940cce20eaaef7fb622f1f9f4f8a0e3e11271d86_SNKRS_1R.png'
      *      ]
      */
     if (isset($context['versioning']) && true === $context['versioning']) {
         return [$this->getFieldName($file, $context) => $file->getKey()];
     }
     /**
      * other case is used by products exports (to retrieve the path of the media for the export)
      *      [
      *          'media' => 'files/SNKRS-1B/side_view/akene-mobile.jpg'
      *      ]
      */
     $identifier = isset($context['identifier']) ? $context['identifier'] : null;
     if (isset($context['value'])) {
         $exportPath = $this->pathGenerator->generate($context['value'], ['identifier' => $identifier]);
         return [$this->getFieldName($file, $context) => $exportPath];
     }
     return [];
 }