/**
  * - 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}
  */
 public function convertLocalizedToDefaultValues(array $items, array $options = [])
 {
     $this->violations = new ConstraintViolationList();
     $attributeTypes = $this->attributeRepository->getAttributeTypeByCodes(array_keys($items));
     foreach ($items as $code => $item) {
         if (isset($attributeTypes[$code])) {
             $localizer = $this->localizerRegistry->getLocalizer($attributeTypes[$code]);
             if (null !== $localizer) {
                 foreach ($item as $index => $data) {
                     $items[$code][$index] = $this->convertLocalizedToDefaultValue($localizer, $data, $options, $this->buildPropertyPath($data, $code));
                 }
             }
         }
     }
     return $items;
 }
 /**
  * {@inheritdoc}
  */
 public function filter(ProductInterface $product, array $newValues)
 {
     $originalValues = $this->getOriginalProduct($product);
     $attributeTypes = $this->attributeRepository->getAttributeTypeByCodes(array_keys($newValues));
     $result = [];
     foreach ($newValues as $code => $value) {
         if (in_array($code, $this->productFields)) {
             $data = $this->compareField($originalValues, $value, $code);
         } elseif (isset($attributeTypes[$code])) {
             $data = $this->compareAttribute($originalValues, $value, $attributeTypes, $code);
         } else {
             throw new \LogicException(sprintf('Cannot filter value of field "%s"', $code));
         }
         if (null !== $data) {
             $result = $this->mergeValueToResult($result, $data);
         }
     }
     return $result;
 }
 /**
  * {@inheritdoc}
  *
  * Before:
  * [
  *     "name": [{
  *         "locale": "fr_FR",
  *         "scope":  null,
  *         "data":  "T-shirt super beau",
  *     }],
  *     "price": [
  *          {
  *              "locale": null,
  *              "scope":  ecommerce,
  *              "data":   [
  *                  {"data": 10.78, "currency": "EUR"},
  *                  {"data": 24, "currency": "USD"},
  *                  {"data": 20.75, "currency": "CHF"}
  *              ]
  *          }
  *     ],
  *     "length": [{
  *         "locale": "en_US",
  *         "scope":  "mobile",
  *         "data":   {"data": 10.45, "unit": "CENTIMETER"}
  *     }]
  *     [...]
  *
  * After:
  * [
  *     "name": [{
  *         "locale": "fr_FR",
  *         "scope":  null,
  *         "data":  "T-shirt super beau",
  *     }],
  *     "price": [
  *          {
  *              "locale": null,
  *              "scope":  ecommerce,
  *              "data":   [
  *                  {"data": "10,78", "currency": "EUR"},
  *                  {"data": "24", "currency": "USD"},
  *                  {"data": "20,75", "currency": "CHF"}
  *              ]
  *          }
  *     ],
  *     "length": [{
  *         "locale": "en_US",
  *         "scope":  "mobile",
  *         "data":   {"data": "10,45", "unit": "CENTIMETER"}
  *     }]
  *     [...]
  */
 public function convertToLocalizedFormats(array $items, array $options = [])
 {
     $attributeTypes = $this->attributeRepository->getAttributeTypeByCodes(array_keys($items));
     foreach ($items as $code => $item) {
         if (isset($attributeTypes[$code])) {
             $localizer = $this->localizerRegistry->getLocalizer($attributeTypes[$code]);
             if (null !== $localizer) {
                 foreach ($item as $index => $data) {
                     $items[$code][$index]['data'] = $localizer->localize($data['data'], $options);
                 }
             }
         }
     }
     return $items;
 }