Shopware 6插件开发:如何正确使用Flysystem Local Adapter
Shopware 6插件中Flysystem Local Adapter实现方案
一、核心思路
Shopware 6已集成Flysystem组件,无需额外安装依赖。我们通过Symfony DI容器注册Local适配器实例,再在命令类中注入使用,完成本地文件的读取、列表等操作。
二、配置服务(DI注册)
在插件src/Resources/config/services.xml中定义Flysystem相关服务:
<?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <!-- 注册Local适配器实例 --> <service id="importer_plugin.filesystem.local" class="League\Flysystem\Local\LocalFilesystemAdapter"> <argument>%kernel.project_dir%/custom/plugins/ImporterPlugin/upload</argument> </service> <!-- 注册Flysystem核心实例 --> <service id="importer_plugin.filesystem" class="League\Flysystem\Filesystem"> <argument type="service" id="importer_plugin.filesystem.local"/> </service> <!-- 注册命令类,注入文件系统实例和环境变量路径 --> <service id="ImporterPlugin\Command\ImportCommand" class="ImporterPlugin\Command\ImportCommand"> <argument type="service" id="importer_plugin.filesystem"/> <argument>%env(IMPORT_CSV_PATH)%</argument> <argument>%env(PRODUCTIMPORTER_MEDIA_SOURCE_PATH)%</argument> <tag name="console.command"/> </service> </services> </container>
三、命令类中实现文件操作
修改ImportCommand.php,注入Flysystem实例并完成业务逻辑:
<?php namespace ImporterPlugin\Command; use League\Flysystem\Filesystem; use League\Flysystem\FilesystemException; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class ImportCommand extends Command { protected static $defaultName = 'importer:import-products'; private $filesystem; private $csvPath; private $mediaSourcePath; public function __construct(Filesystem $filesystem, string $csvPath, string $mediaSourcePath) { parent::__construct(); $this->filesystem = $filesystem; $this->csvPath = $csvPath; $this->mediaSourcePath = $mediaSourcePath; } protected function configure() { $this->setDescription('Import products from CSV and process local media files'); } protected function execute(InputInterface $input, OutputInterface $output): int { $output->writeln('Starting product import process...'); try { // 1. 读取CSV文件内容 $relativeCsvPath = $this->getRelativePath($this->csvPath); $csvContent = $this->filesystem->read($relativeCsvPath); $output->writeln('✅ Successfully read CSV file'); // 2. 列出媒体目录下的所有文件 $relativeMediaPath = $this->getRelativePath($this->mediaSourcePath); $mediaFiles = $this->filesystem->listContents($relativeMediaPath, true); $output->writeln('🔍 Found ' . count($mediaFiles) . ' media files'); // 3. 逐个处理媒体文件 foreach ($mediaFiles as $file) { if (!$file->isFile()) continue; $fileContent = $this->filesystem->read($file->path()); // 这里可添加Shopware媒体库上传逻辑,结合MediaService实现 $output->writeln('📦 Processed media file: ' . $file->filename()); } } catch (FilesystemException $e) { $output->writeln('<error>❌ Import failed: ' . $e->getMessage() . '</error>'); return Command::FAILURE; } $output->writeln('<info>🎉 Product import completed successfully!</info>'); return Command::SUCCESS; } // 计算相对于upload目录的路径 private function getRelativePath(string $absolutePath): string { $baseUploadDir = rtrim(dirname($this->csvPath), '/'); return str_replace($baseUploadDir . '/', '', $absolutePath); } }
四、调用方式
直接在命令行执行插件注册的命令即可触发逻辑:
bin/console importer:import-products
五、注意事项
- 确保
upload目录权限正确(建议设置为755,用户组为www-data),避免读写失败 - 校验
.env中的绝对路径与服务器实际路径一致 - 若需将媒体文件同步到Shopware媒体库,可结合Shopware自带的
MediaService类完成上传逻辑
内容的提问来源于stack exchange,提问作者balrcoding
相关产品推荐
相关产品推荐

