【问题标题】:FilePrg with collections on ZF2FilePrg 与 ZF2 上的集合
【发布时间】:2014-07-29 21:30:11
【问题描述】:

我需要提交一个表单,其中包含一些字段以及最多 3 张图片的集合,使用 fileprg 插件保存上传的文件,以防出现一些验证错误。

我不想切换到不同的解决方案(比如将表单拆分为子表单,或者删除集合以支持三个不同的文件字段)。我遇到的主要问题是,当用户提交无效文件(太大,或使用无效的 mimetype )时,我想报告错误并允许上传不同的文件。相反,集合从表单中消失了。

如果用户根本不提交文件,即使需要文件,也会发生同样的情况。 在用我自己的代码测试后,我决定在 cgmartin 代码上进行测试,无论如何都会发生这种情况。

我知道这可能会像 this question 的副本一样被禁止,但我被这个问题困住了几天。

这是我的 cgmartin 代码的“分支”(我实际上在控制器中添加了 fileprg,视图和表单保持不变)。 谢谢。 A.

public function collectionAction()
{
    $form = new Form\CollectionUpload('file-form');
    $prg = $this->fileprg($form);


    if ($prg instanceof \Zend\Http\PhpEnvironment\Response) {
        $this->getServiceLocator()->get('Zend/Log')->debug("Redirect to Get!");
        return $prg; // Return PRG redirect response
    } elseif (is_array($prg)) {


            if ($form->isValid()) {
                //
                // ...Save the form...
                //
                return $this->redirectToSuccessPage($form->getData());
            }

    }

    return array('form' => $form);
}

景色

<div>
 <a href="<?php echo $this->url('fileupload')?>">&laquo; Back to Examples Listing</a>
</div>

<h2><?php echo ($this->title) ?: 'File Upload Examples' ?></h2>

<?php
// Init Form
$form = $this->form;
$form->setAttribute('class', 'form-horizontal');
$form->prepare();

// Configure Errors Helper
$errorsHelper  = $this->plugin('formelementerrors');
$errorsHelper
    ->setMessageOpenFormat('<div class="help-block">')
    ->setMessageSeparatorString('</div><div class="help-block">')
    ->setMessageCloseString('</div>');
?>
<?php echo $this->form()->openTag($form); ?>
<fieldset>
    <legend><?php echo ($this->legend) ?: 'Multi-File Upload with Collections' ?></legend>

    <?php
    $elem = $form->get('text');
    $elem->setLabelAttributes(array('class' => 'control-label'));
    $errors = $elem->getMessages();
    $errorClass = (!empty($errors)) ? ' error' : '';
    ?>
    <div class="control-group<?php echo $errorClass ?>">
        <?php echo $this->formLabel($elem); ?>
        <div class="controls">
            <?php echo $this->formText($elem); ?>
            <?php echo $errorsHelper($elem); ?>
        </div>
    </div>

    <?php
    $collection = $form->get('file-collection');
    foreach ($collection as $elem) {
        $elem->setLabelAttributes(array('class' => 'control-label'));
        $errors = $elem->getMessages();
        $errorClass = (!empty($errors)) ? ' error' : '';
        ?>
        <div class="control-group<?php echo $errorClass ?>">
            <?php echo $this->formLabel($elem); ?>
            <div class="controls">
                <?php echo $this->formFile($elem); ?>
                <?php echo $errorsHelper($elem); ?>
            </div>
        </div>
        <?php
    }
    ?>
    <?php if (!empty($this->tempFiles)) { ?>
    <div class="control-group"><div class="controls">
        <div class="help-block">
            Uploaded: <ul>
            <?php foreach ($this->tempFiles as $tempFile) { ?>
            <li><?php echo $this->escapeHtml($tempFile['name']) ?></li>
            <?php } ?>
            </ul>
        </div>
    </div></div>
    <?php } ?>

    <div class="control-group">
        <div class="controls">
            <button class="btn btn-primary">Submit</button>
        </div>
    </div>

</fieldset>
<?php echo $this->form()->closeTag($form); ?>

形式:

<?php

namespace ZF2FileUploadExamples\Form;

use Zend\InputFilter;
use Zend\Form\Form;
use Zend\Form\Element;

class CollectionUpload extends Form
{
    public $numFileElements = 2;

    public function __construct($name = null, $options = array())
    {
        parent::__construct($name, $options);
        $this->addElements();
        $this->setInputFilter($this->createInputFilter());
    }

    public function addElements()
    {
        // File Input
        $file = new Element\File('file');
        $file->setLabel('Multi File');

        $fileCollection = new Element\Collection('file-collection');
        $fileCollection->setOptions(array(
             'count'          => $this->numFileElements,
             'allow_add'      => false,
             'allow_remove'   => false,
             'target_element' => $file,
        ));
        $this->add($fileCollection);

        // Text Input
        $text = new Element\Text('text');
        $text->setLabel('Text Entry');
        $this->add($text);
    }

    public function createInputFilter()
    {
        $inputFilter = new InputFilter\InputFilter();

        // File Collection
        $fileCollection = new InputFilter\InputFilter();
        for ($i = 0; $i < $this->numFileElements; $i++) {
            $file = new InputFilter\FileInput($i);
            $file->setRequired(true);
            $file->getFilterChain()->attachByName(
                'filerenameupload',
                array(
                    'target'          => './data/tmpuploads/',
                    'overwrite'       => true,
                    'use_upload_name' => true,
                )
            );
            $fileCollection->add($file);
        }
        $inputFilter->add($fileCollection, 'file-collection');

        // Text Input
        $text = new InputFilter\Input('text');
        $text->setRequired(true);
        $inputFilter->add($text);

        return $inputFilter;
    }
}

【问题讨论】:

    标签: php file-upload collections zend-framework2 post-redirect-get


    【解决方案1】:

    我看不到您将数据设置到表单的位置,这可能是在呈现表单错误时不维护它的原因。

    您应该在验证表单之前调用$form-&gt;setData($prg);

    我的基本逻辑通常是这样的:

    if ($prg instanceof \Zend\Http\PhpEnvironment\Response) {
        return $prg; // Return PRG redirect response
    } elseif ($prg !== false) {
        // Set data to form
        $form->setData($prg);
    
        // Validate form
        if ($form->isValid()) {
             // ...Save the form...
        } else {
            // Do something else
        }
    } else {
          // first time Page is called
    }
    
    // Always show form
    return new ViewModel(array('form' => $form));
    

    【讨论】:

    • 嗨 chandlermania,感谢您的支持。我按照您的建议尝试了,但不幸的是没有任何改变。对我来说看起来很奇怪的是,没有 fileprg 它实际上可以按预期工作:(
    • @AlessioDeZotti 你找到解决方案了吗?
    【解决方案2】:

    我只是快速浏览了一下代码,只是为了给你一个大纲而突出显示核心:请不要崇拜它,因为我在分享之前没有时间审查和测试它。看起来我发现的解决方法是将有效文件存储在会话中:希望这会有所帮助

    try {
            $viewModel = new ViewModel();
    
            //init the session container for files
            if(!isset($this->sessionContainer->files))
                $this->sessionContainer->files = array();
    
            $frmNotifyEvent = $this->getServiceLocator()->get('FormElementManager')->get('Frontend\Form\ReportEvent');
    
            $events = $this->getServiceLocator()->get("Events_Event");
    
            $prg = $this->fileprg($frmNotifyEvent);
    
            if ($prg instanceof \Zend\Http\PhpEnvironment\Response) {
                return $prg; // Return PRG redirect response
            } elseif (is_array($prg)) {
    
                if ($frmNotifyEvent->isValid())
                {
                    $event = $frmNotifyEvent->getObject();
    
                    for($i=1; $i<=3; $i++)
                    {
                        $fileErrors = $frmNotifyEvent->get("file$i")->getMessages();
                        if ($frmNotifyEvent->get("file$i")->getValue() && empty($fileErrors)) {
                            $this->sessionContainer->files[$i] = $frmNotifyEvent->get("file$i")->getValue();
                        }
    
                        if(isset($this->sessionContainer->files[$i]))
                        {
                            $asset = $this->getServiceLocator()->get("Application_AssetService")->fromDisk($this->sessionContainer->files[$i]['tmp_name'], $this->sessionContainer->files[$i]['name']);
                            // then save the file 
                        }
                    }
    
    
                    //clean files
                    $this->sessionContainer->files = null;
                    return $this->redirectToSuccessPage($frmNotifyEvent->getData());
                }
                else {
                    for($i=1; $i<=3; $i++)
                    {
                        $fileErrors = $frmNotifyEvent->get("file$i")->getMessages();
                        if ($frmNotifyEvent->get("file$i")->getValue() && empty($fileErrors)) {
                            $this->sessionContainer->files[$i] = $frmNotifyEvent->get("file$i")->getValue();
                        }
                    }
    
    
    
                    $viewModel->setVariable("error", 'dic.form_has_upload_errors');
                }
                $viewModel->setVariable("post", $prg)
                    ->setVariable("tempFiles", $this->sessionContainer->files);
            }
            $viewModel->setVariable("frmReportEvent", $frmNotifyEvent);
    
            return $viewModel;
    
        } catch(Exception $e)
        {
            throw $e;
        }`
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-28
      • 1970-01-01
      • 2014-09-06
      • 1970-01-01
      相关资源
      最近更新 更多