首页 文章

VichUploaderBundle:如何在DirectoryNamer中获取相关的实体ID?

提问于
浏览
2

我正在配置VichUploaderBundle中包含的directory namer来上传多个文件 .

我有两个实体 SoundtrackSong . Song 的集合在我的控制器中处理如下:

//...
if ($form->isValid()) {
   $soundtrack->setSlug("sw-ep-vii");
   $soundtrack->setName("Star Wars Episode VII");
   foreach ($soundtrack->getSongs() as $song) {
      $em->persist($song);
   }
   $em->persist($soundtrack);
   $em->flush();
}

当持久 $soundtrack VichUploaderBundle 上传 Song 文件并将它们移动到 config.yml 中定义的目录或者移动到名为 DirectoryNamer 的服务中定义的动态路由时,这是我感兴趣的 .

在我的 SoundtrackDirectoryNamer 中,持久的 Song 实体自动传递给 directoryName() 方法,所以我想只返回关联的 Soundtrack.id 作为目录名,如:

class SoundtrackDirectoryNamer implements DirectoryNamerInterface
{
    public function directoryName($song, PropertyMapping $mapping)
    {   
        return $song->getSoundtrack()->getId();                                                                                    
    }
}

现在问题是 Soundtrack 仍未持久保存到数据库,因此它还没有自动递增的 id .

如果我将 $song->getSoundtrack()->getId() 更改为 $song->getSoundtrack()->getSlug() ,它会正确创建目录 sw-ep-vii 并且一切正常 - 因为我之前使用 $soundtrack->setSlug("sw-ep-vii") 在控制器中设置了slug .

对此有何解决方法?

2 回答

  • 4

    我是捆绑的当前维护者 .

    那个's a known issue (to be exact, it'更多的不会修复 .

    实际保存了实体的目录和文件名 before ,因此对于新对象,标识符不可用 . 按照设计,除了你不使用自动递增的标识符而是使用生成的标识符(例如UUID或slugs)之外,没有什么可以做到的 .

  • 0

    实际上有一种解决方案,即使它在所有情况下都不是完全可靠的 . 下面是一个与MySQL兼容的示例方法,您可以将其放入您的命名类中以获取新实体的预期ID(预先假定注入的实体管理器):

    protected function getNextAutoIncrementedId($object) {
      $meta = $this->em->getClassMetadata(get_class($object));
      if(!$meta) return null;
    
      $conn = $this->em->getConnection();
      $table = $meta->getTableName();
      $sql = "SHOW TABLE STATUS WHERE `Name` = '$table'";
      $result = $conn->query($sql)->fetch(\PDO::FETCH_ASSOC);
      if(empty($result['Auto_increment'])) return null;
    
      return $result['Auto_increment'];
    }
    

相关问题