- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我目前正面临 SonataAdminBundle、一对多关系和文件上传方面的挑战。我有一个名为 Client
的实体还有一个叫ExchangeFile
.一Client
可以有几个 ExchangeFile
s,所以我们这里是一对多的关系。我正在使用 VichUploaderBundle用于文件上传。
这是 Client
类:
/**
* @ORM\Table(name="client")
* @ORM\Entity()
* @ORM\HasLifecycleCallbacks
*/
class Client extends BaseUser
{
// SNIP
/**
* @ORM\OneToMany(targetEntity="ExchangeFile", mappedBy="client", orphanRemoval=true, cascade={"persist", "remove"})
*/
protected $exchangeFiles;
// SNIP
}
这是ExchangeFile
类:
/**
* @ORM\Table(name="exchange_file")
* @ORM\Entity
* @Vich\Uploadable
*/
class ExchangeFile
{
// SNIP
/**
* @Assert\File(
* maxSize="20M"
* )
* @Vich\UploadableField(mapping="exchange_file", fileNameProperty="fileName")
*/
protected $file;
/**
* @ORM\Column(name="file_name", type="string", nullable=true)
*/
protected $fileName;
/**
* @ORM\ManyToOne(targetEntity="Client", inversedBy="exchangeFiles")
* @ORM\JoinColumn(name="client_id", referencedColumnName="id")
*/
protected $client;
// SNIP
}
在我的 ClientAdmin
类,我添加了 exchangeFiles
按以下方式填写:
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
// SNIP
->with('Files')
->add('exchangeFiles', 'sonata_type_collection', array('by_reference' => false), array(
'edit' => 'inline',
'inline' => 'table',
))
// SNIP
}
这允许在客户端编辑表单中对各种交换文件进行内联编辑。到目前为止效果很好: .
问题
但有一个注意事项:当我点击绿色“+”号时(添加一个新的交换文件表单行),然后在我的文件系统中选择一个文件,然后点击“+”号再次(通过 Ajax 附加一个新的表单行),选择另一个文件,然后点击“更新”(保存当前客户端),然后第一个文件不会被保留。在数据库和文件系统中只能找到第二个文件。
据我所知,这有以下原因:当第二次点击绿色“+”号时,当前表单被发送到网络服务器,包括当前表单中的数据(客户端和所有交换文件)。创建一个新表单并将请求绑定(bind)到表单中(这发生在位于 AdminHelper
的 Sonata\AdminBundle\Admin
类中):
public function appendFormFieldElement(AdminInterface $admin, $subject, $elementId)
{
// retrieve the subject
$formBuilder = $admin->getFormBuilder();
$form = $formBuilder->getForm();
$form->setData($subject);
$form->bind($admin->getRequest()); // <-- here
// SNIP
}
因此整个表单被绑定(bind),表单行被附加,表单被发送回浏览器并且整个表单被新表单覆盖。但由于出于安全原因无法预填充文件输入 ( <input type="file" />
),因此第一个文件丢失了。该文件仅在实体持久化时存储在文件系统中(我认为 VichUploaderBundle
为此使用了 Doctrine 的 prePersist
),但是当附加表单字段行时,这还不会发生。
我的第一个问题是:我该如何解决这个问题,或者我应该往哪个方向走?我希望以下用例起作用:我想创建一个新客户端,我知道我将上传三个文件。我单击“新建客户端”,输入客户端数据,点击一次绿色“+”按钮,选择第一个文件。然后我再次点击“+”号,并选择第二个文件。第三个文件也一样。所有三个文件都应保留。
第二个问题:当我只想在一对多关系中添加单个表单行时,为什么 Sonata Admin 会发布整个表单?这真的有必要吗?这意味着如果我有文件输入,则每次添加新的表单行时都会上传表单中存在的所有文件。
在此先感谢您的帮助。如果您需要任何详细信息,请告诉我。
最佳答案
进一步补充我对 SonataMediaBundle 的评论...
如果您确实采用这条路线,那么您会想要创建一个类似于以下内容的新实体:
/**
* @ORM\Table
* @ORM\Entity
*/
class ClientHasFile
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var Client $client
*
* @ORM\ManyToOne(targetEntity="Story", inversedBy="clientHasFiles")
*/
private $client;
/**
* @var Media $media
*
* @ORM\ManyToOne(targetEntity="Application\Sonata\MediaBundle\Entity\Media")
*/
private $media;
// SNIP
}
然后,在您的客户实体中:
class Client
{
// SNIP
/**
* @var \Doctrine\Common\Collections\ArrayCollection
*
* @ORM\OneToMany(targetEntity="ClientHasFile", mappedBy="client", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $clientHasFiles;
public function __construct()
{
$this->clientHasFiles = new ArrayCollection();
}
// SNIP
}
...和您的 ClientAdmin 的 configureFormFields:
protected function configureFormFields(FormMapper $form)
{
$form
// SNIP
->add('clientHasFiles', 'sonata_type_collection', array(
'required' => false,
'by_reference' => false,
'label' => 'Media items'
), array(
'edit' => 'inline',
'inline' => 'table'
)
)
;
}
...最后但同样重要的是,您的 ClientHasFileAdmin 类:
class ClientHasFileAdmin extends Admin
{
/**
* @param \Sonata\AdminBundle\Form\FormMapper $form
*/
protected function configureFormFields(FormMapper $form)
{
$form
->add('media', 'sonata_type_model_list', array(), array(
'link_parameters' => array('context' => 'default')
))
;
}
/**
* {@inheritdoc}
*/
protected function configureListFields(ListMapper $list)
{
$list
->add('client')
->add('media')
;
}
}
关于php - Sonata Admin与文件上传的一对多关系(appendFormFieldElement),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13648467/
我在 JavaScript 文件中运行 PHP,例如...... var = '';). 我需要使用 JavaScript 来扫描字符串中的 PHP 定界符(打开和关闭 PHP 的 )。 我已经知道使
我希望能够做这样的事情: php --determine-oldest-supported-php-version test.php 并得到这个输出: 7.2 也就是说,php 二进制检查 test.
我正在开发一个目前不使用任何框架的大型 php 站点。我的大问题是,随着时间的推移慢慢尝试将框架融入应用程序是否可取,例如在创建的新部件和更新的旧部件中? 比如所有的页面都是直接通过url服务的,有几
下面是我的源代码,我想在同一页面顶部的另一个 php 脚本中使用位于底部 php 脚本的变量 $r1。我需要一个简单的解决方案来解决这个问题。我想在代码中存在的更新查询中使用该变量。 $name)
我正在制作一个网站,根据不同的情况进行大量 PHP 重定向。就像这样...... header("Location: somesite.com/redirectedpage.php"); 为了安全起见
我有一个旧网站,我的 php 标签从 因为短标签已经显示出安全问题,并且在未来的版本中将不被支持。 关于php - 如何避免在 php 文件中写入
我有一个用 PHP 编写的配置文件,如下所示, 所以我想用PHP开发一个接口(interface),它可以编辑文件值,如$WEBPATH , $ACCOUNTPATH和 const值(value)观
我试图制作一个登录页面来学习基本的PHP,首先我希望我的独立PHP文件存储HTML文件的输入(带有表单),但是当我按下按钮时(触发POST到PHP脚本) )我一直收到令人不愉快的错误。 我已经搜索了S
我正在寻找一种让 PHP 以一种形式打印任意数组的方法,我可以将该数组作为赋值包含在我的(测试)代码中。 print_r 产生例如: Array ( [0] => qsr-part:1285 [1]
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: What is the max key size for an array in PHP? 正如标题所说,我想知道
我正在寻找一种让 PHP 以一种形式打印任意数组的方法,我可以将该数组作为赋值包含在我的(测试)代码中。 print_r 产生例如: Array ( [0] => qsr-part:1285 [1]
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
我在 MySQL 数据库中有一个表,其中存储餐厅在每个工作日和时段提供的菜单。 表结构如下: i_type i_name i_cost i_day i_start i_
我有两页。 test1.php 和 test2.php。 我想做的就是在 test1.php 上点击提交,并将 test2.php 显示在 div 中。这实际上工作正常,但我需要向 test2.php
我得到了这个代码。我想通过textarea更新mysql。我在textarea中回显我的MySQL,但我不知道如何更新它,我应该把所有东西都放进去吗,因为_GET模式没有给我任何东西,我也尝试_GET
首先,我是 php 的新手,所以我仍在努力学习。我在 Wordpress 上创建了一个表单,我想将值插入一个表(data_test 表,我已经管理了),然后从 data_test 表中获取所有列(id
我有以下函数可以清理用户或网址的输入: function SanitizeString($var) { $var=stripslashes($var); $va
我有一个 html 页面,它使用 php 文件查询数据库,然后让用户登录,否则拒绝访问。我遇到的问题是它只是重定向到 php 文件的 url,并且从不对发生的事情提供反馈。这是我第一次使用 html、
我有一个页面充满了指向 pdf 的链接,我想跟踪哪些链接被单击。我以为我可以做如下的事情,但遇到了问题: query($sql); if($result){
我正在使用 从外部文本文件加载 HTML/PHP 代码 $f = fopen($filename, "r"); while ($line = fgets($f, 4096)) { print $l
我是一名优秀的程序员,十分优秀!