问题描述
我正在努力通过PHP导入媒体以使Shopware 6正常工作。
这是我的服务
<?PHP declare(strict_types=1);
namespace My\Namespace\Service;
use Shopware\Core\Content\Media\File\MediaFile;
use Shopware\Core\Content\Media\MediaService;
use Shopware\Core\Framework\Context;
class ImageImport
{
/**
* @var MediaService
*/
protected $mediaService;
/**
* ImageImport constructor.
* @param MediaService $mediaService
*/
public function __construct(MediaService $mediaService)
{
$this->mediaService = $mediaService;
}
public function addImagetoProductMedia($imageUrl,Context $context)
{
$mediaId = NULL;
$context->disableCache(function (Context $context) use ($imageUrl,&$mediaId): void {
$filePathParts = explode('/',$imageUrl);
$fileName = array_pop($filePathParts);
$fileNameParts = explode('.',$fileName);
$actualFileName = $fileNameParts[0];
$fileExtension = $fileNameParts[1];
if ($actualFileName && $fileExtension) {
$tempFile = tempnam(sys_get_temp_dir(),'image-import');
file_put_contents($tempFile,file_get_contents($imageUrl));
$fileSize = filesize($tempFile);
$mimeType = mime_content_type($tempFile);
$mediaFile = new MediaFile($tempFile,$mimeType,$fileExtension,$fileSize);
$mediaId = $this->mediaService->saveMediaFile($mediaFile,$actualFileName,$context,'product');
}
});
return $mediaId;
}
}
在表媒体中创建具有正确media_folder_association的条目。据我所知,与通过后端上传的其他媒体没有区别(私有为1,user_id为NULL除外)。
但是在后端,媒体条目已损坏,似乎无法加载实际的图像文件(我尝试将private设置为true以便在媒体部分中看到它,将媒体添加到产品中时也会发生同样的情况通过PHP,但我想问题出在对产品的任何分配之前。)
有人建议这里有什么问题吗?
谢谢 菲尔
=====解决方案======
这是已更新且可以使用的服务:
<?PHP declare(strict_types=1);
namespace My\Namespace\Service;
use Shopware\Core\Content\Media\File\FileSaver;
use Shopware\Core\Content\Media\File\MediaFile;
use Shopware\Core\Content\Media\MediaService;
use Shopware\Core\Framework\Context;
class ImageImport
{
/**
* @var MediaService
*/
protected $mediaService;
/**
* @var FileSaver
*/
private $fileSaver;
/**
* ImageImport constructor.
* @param MediaService $mediaService
* @param FileSaver $fileSaver
*/
public function __construct(MediaService $mediaService,FileSaver $fileSaver)
{
$this->mediaService = $mediaService;
$this->fileSaver = $fileSaver;
}
public function addImagetoProductMedia($imageUrl,$fileSize);
$mediaId = $this->mediaService->createMediaInFolder('product',false);
$this->fileSaver->persistFiletoMedia(
$mediaFile,$mediaId,$context
);
}
});
return $mediaId;
}
}
解决方法
要将文件导入Shopware 6,需要执行两个步骤:
- 您必须创建一个媒体文件对象(
MediaDefinition / media table
)。看看MediaConverter - 在
SwagMigrationMediaFileDefinition
(swag_migration_media_file
表)中创建一个新条目。
相关迁移运行的swag_migration_media_file
表中的每个条目将由MediaFileProcessorInterface的实现处理。
要向表中添加文件,您可以在 Converter 类中执行以下操作(此示例来自MediaConverter):
abstract class MediaConverter extends ShopwareConverter
{
public function convert(
array $data,Context $context,MigrationContextInterface $migrationContext
): ConvertStruct {
$this->generateChecksum($data);
$this->context = $context;
$this->locale = $data['_locale'];
unset($data['_locale']);
$connection = $migrationContext->getConnection();
$this->connectionId = '';
if ($connection !== null) {
$this->connectionId = $connection->getId();
}
$converted = [];
$this->mainMapping = $this->mappingService->getOrCreateMapping(
$this->connectionId,DefaultEntities::MEDIA,$data['id'],$context,$this->checksum
);
$converted['id'] = $this->mainMapping['entityUuid'];
if (!isset($data['name'])) {
$data['name'] = $converted['id'];
}
$this->mediaFileService->saveMediaFile(
[
'runId' => $migrationContext->getRunUuid(),'entity' => MediaDataSet::getEntity(),// important to distinguish between private and public files
'uri' => $data['uri'] ?? $data['path'],'fileName' => $data['name'],// uri or path to the file (because of the different implementations of the gateways)
'fileSize' => (int) $data['file_size'],'mediaId' => $converted['id'],// uuid of the media object in Shopware 6
]
);
unset($data['uri'],$data['file_size']);
$this->getMediaTranslation($converted,$data);
$this->convertValue($converted,'title',$data,'name');
$this->convertValue($converted,'alt','description');
$albumMapping = $this->mappingService->getMapping(
$this->connectionId,DefaultEntities::MEDIA_FOLDER,$data['albumID'],$this->context
);
if ($albumMapping !== null) {
$converted['mediaFolderId'] = $albumMapping['entityUuid'];
$this->mappingIds[] = $albumMapping['id'];
}
unset(
$data['id'],// Legacy data which don't need a mapping or there is no equivalent field
$data['path'],$data['type'],$data['extension'],$data['file_size'],$data['width'],$data['height'],$data['userID'],$data['created']
);
$returnData = $data;
if (empty($returnData)) {
$returnData = null;
}
$this->updateMainMapping($migrationContext,$context);
// The MediaWriter will write this Shopware 6 media object
return new ConvertStruct($converted,$returnData,$this->mainMapping['id']);
}
}
swag_migration_media_files
由正确的处理器服务处理。对于文档和普通媒体,此服务有所不同,但仍取决于网关
===不同的方法(Shyim建议)===
看看这个(取自Shopwaredowntown的Github存储库):
public function upload(UploadedFile $file,string $folder,string $type,Context $context): string
{
$this->checkValidFile($file);
$this->validator->validate($file,$type);
$mediaFile = new MediaFile($file->getPathname(),$file->getMimeType(),$file->getClientOriginalExtension(),$file->getSize());
$mediaId = $this->mediaService->createMediaInFolder($folder,false);
try {
$this->fileSaver->persistFileToMedia(
$mediaFile,pathinfo($file->getFilename(),PATHINFO_FILENAME),$mediaId,$context
);
} catch (MediaNotFoundException $e) {
throw new UploadException($e->getMessage());
}
return $mediaId;
}
src / Portal / Hacks / StorefrontMediaUploader.php:49
public function upload(UploadedFile $file,Context $context): string