Контактная форма Yii с вложениями с YiiMailer: не удается передать имена файлов в контроллер из представления

Не могу прикрепить файлы к электронному письму из контактной формы. Контроллер не получает имена вложений.

моя форма: вид/сайт/contact.php

<div class="form">

<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'contact-form',
    'enableAjaxValidation'=>true,
)); ?>

    <?php echo $form->errorSummary($model); ?>

    <div class="row">
        <?php echo $form->labelEx($model,'name'); ?>
        <?php echo $form->textField($model,'name'); ?>
        <?php echo $form->error($model,'name'); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($model,'email'); ?>
        <?php echo $form->textField($model,'email'); ?>
        <?php echo $form->error($model,'email'); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($model,'subject'); ?>
        <?php echo $form->textField($model,'subject',array('size'=>50,'maxlength'=>128)); ?>
        <?php echo $form->error($model,'subject'); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($model,'body'); ?>
        <?php echo $form->textArea($model,'body',array('rows'=>6, 'cols'=>40)); ?>
        <?php echo $form->error($model,'body'); ?>
    </div>

<label>Приложить файлы:</label>
<div id="attachments"></div>
<?php $this->widget('ext.EAjaxUpload.EAjaxUpload',
    array(
        'id'=>'attachmentsUpload' . mt_rand(0,100),
        'config'=> $this->getUploadConfig(),
    )
);
?>


    <?php if(extension_loaded('gd')): ?>
    <div class="row">
        <?php echo $form->labelEx($model,'verifyCode'); ?>
        <div>

        <?php $this->widget('CCaptcha', array('clickableImage'=>false, 'showRefreshButton'=>true, 'buttonLabel' => CHtml::image(Yii::app()->baseUrl
                                . '/css/icon_refresh.png'),'imageOptions'=>array('style'=>'/*display:block;*/border:none;', 'height'=>'50px', 'alt'=>'Картинка с кодом валидации'))); ?>
<br />
        <div><?php echo $form->textField($model,'verifyCode'); ?></div>
        <?php echo $form->error($model,'verifyCode'); ?>
        </div>

    </div>
    <?php endif; ?>

    <div class="row submit">
        <?php echo CHtml::submitButton('Отправить'); ?>
    </div>

<?php $this->endWidget(); ?>

</div><!-- form -->

действие в контроллерах/SiteController.php

public function actionContact()
    {      
        $this->layout = '//layouts/column2_with_quick_form';

        $model=new ContactForm('insert'); 
        if(isset($_POST['ajax']) && $_POST['ajax']==='contact-form')
        {
            $model->setScenario('ajax');
            echo CActiveForm::validate($model);
            Yii::app()->end();
        }
        if(isset($_POST['ContactForm']))
        {
            $model->attributes=$_POST['ContactForm'];
            if($model->validate())
            {
                //use 'contact' view from views/mail
                $mail = new YiiMailer('contact', array('message' => $model->body, 'name' => $model->name, 'description' => 'Сообщение с сайта'));

                //set properties
                $mail->setFrom($model->email, $model->name);
                $mail->setSubject($model->subject);
                $mail->setTo(Yii::app()->params['adminEmail']);


                foreach ($model->attachments as $file) {
            //echo($file->name);
            $path = Yii::app()->basePath . '/tmp/attachments/' . $file->name;
            //$file->saveAs($path); //save the file to the $path
            $mail->setAttachment($path);
            //unlink(Yii::app()->basePath . '/data/' . $file->name);
        }       

                //send
                if ($mail->send()) {
                    Yii::app()->user->setFlash('contact','Спасибо за ваше письмо! Мы ответим вам в ближайшее время.');
                    Yii::app()->getController()->createAction('captcha')->getVerifyCode(true);
                } else {
                    Yii::app()->user->setFlash('error','Какая-то ошибка: '.$mail->getError());
                }

                $this->refresh();
            }
        }
        $this->render('contact',array('model'=>$model));
    }

Здесь $model->attachments пусто. В моделях/ContactForm.php он существует:

class ContactForm extends CFormModel
{
    ...
    public $attachments;

    /**
     * Declares the validation rules.
     */
    public function rules()
    {
        return array(
            // name, email, subject and body are required
            array('name, email, subject, body', 'required'),
            // email has to be a valid email address
            array('email', 'email'),
            array('attachments', 'safe'),
...

Вот getUploadConfig и actionUpload

public function getUploadConfig()
  {
      return array(
          'action'=> Yii::app()->createUrl('site/upload'),
          'allowedExtensions'=>array(),//array("jpg","jpeg","gif","exe","mov" and etc...
          'sizeLimit'=>ini_get('upload_max_filesize')*1024*1024,// maximum file size in bytes
          'onComplete'=>"js:function(id, fileName, responseJSON) {
                            $('#attachments').append('<div id=\"' + responseJSON.spanid + '\"><input type=\"hidden\" name=\"ContactForm[attachments][]\" value=\"' + responseJSON.filename + '\"/><a target=\"_blank\" href=\"/tmp/attachments/' + responseJSON.filename + '\">' + responseJSON.filename + '</a> - <a href=\"javascript:jQuery(\'#' + responseJSON.spanid  + '\').remove();void(0);\">[удалить]</a>&nbsp;&nbsp;&nbsp;</div>'); 
                    }",
          'messages'=>array(
                           'typeError'=>"{file} has invalid extension. Only {extensions} are allowed.",
                           'sizeError'=>"{file} is too large, maximum file size is {sizeLimit}.",
                           'minSizeError'=>"{file} is too small, minimum file size is {minSizeLimit}.",
                           'emptyError'=>"{file} is empty, please select files again without it.",
                           'onLeave'=>"The files are being uploaded, if you leave now the upload will be cancelled."
                          ),
          'showMessage'=>"js:function(message){ alert(message); }"
      );
  }

  public function actionUpload()
  {
      Yii::import("ext.EAjaxUpload.qqFileUploader");
      $folder = 'tmp'.DIRECTORY_SEPARATOR.'attachments'.DIRECTORY_SEPARATOR;
      $this->createDirectory($_SERVER['DOCUMENT_ROOT'].Yii::app()->urlManager->baseUrl.DIRECTORY_SEPARATOR.$folder);
    $uploader = new qqFileUploader(array(), ini_get('upload_max_filesize')*1024*1024);
      $result = $uploader->handleUpload($folder);
      $path = YiiBase::getPathOfAlias('webroot').DIRECTORY_SEPARATOR.$folder;
      if ($result['success'])
          $result['spanid'] = mktime();
      echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);
  }

Файлы загружаются на сервер в tmp/attachments, но не прикрепляются к электронной почте. эта строка работает хорошо:

$mail->setAttachment('tmp/attachments'.'/filename.jpg');

Итак, я думаю, что проблема с $model->attachments в контроллере

Пожалуйста, помогите решить ее.


person almix    schedule 03.10.2014    source источник


Ответы (2)


Что происходит, когда вы добавляете эту строку кода в виджет формы?

'htmlOptions' => array(
    'enctype' => 'multipart/form-data',
),
person Prabowo Murti    schedule 05.10.2014
comment
Прабово, это не помогает, потому что $model-›attachments пуст. Я не нашел, как передать этот параметр из представления в контроллер. - person almix; 06.10.2014

Я нашел другое решение. Я отказываюсь использовать EAjaxUpload. Вместо этого используйте CMultiFileUpload. Напишите решение здесь - http://loco.ru/materials/485-contact-form-with-multiple-files-cmultifileupload-yiimailer Работает отлично! Контактная форма с вложенными файлами по электронной почте. Теперь кратко расскажу здесь.

Посмотреть:

<div class="row">
<?php echo $form->labelEx($model,'attachments'); ?>
<?php  $this->widget('CMultiFileUpload',
array(
      'model'=>$model,
      'attribute' => 'attachments',
      'accept'=> 'jpg,jpeg,gif,png,doc,docx,pdf,txt',
      'denied'=>'Разрешаем аттачить только форматы: jpg,jpeg,gif,png,doc,docx,pdf,txt', 
      'max'=>4,
      'remove'=>'[x]',
      'duplicate'=>'Вы уже прикрепили файл с таким именем. Давайте внимательней!',
      )
);?>
<?php echo $form->error($model,'attachments'); ?>
<div class="hint">Не больше 4-х вложений.</div>
</div>

в модели:

class ContactForm extends CFormModel
{
...
public $attachments;

/**
* Declares the validation rules.
*/
public function rules()
{
return array(
...
array('attachments', 'file', 
'types'=>'jpg,jpeg,gif,png,doc,docx,pdf,txt',
'maxSize'=>1024 * 1024 * 1, // 1MB
'tooLarge'=>'The file was larger than 1MB. Please upload a smaller file.',
'allowEmpty'=>1,
),
...
);
}
...

в контроллере:

public function actionContact()
{      
$this->layout = '//layouts/column2_with_quick_form';

$model=new ContactForm('insert'); 
if(isset($_POST['ajax']) && $_POST['ajax']==='contact-form') //тут ajax-валидация
{
$model->setScenario('ajax'); // метод, устанавливающий сценарий 'ajax'
echo CActiveForm::validate($model);
Yii::app()->end();
}
if(isset($_POST['ContactForm']))
{
$model->attributes=$_POST['ContactForm'];
if($model->validate())
{
//используем представление 'contact' из директории views/mail
$mail = new YiiMailer('contact', array('message' => $model->body, 'name' => $model->name, 'description' => 'Сообщение с сайта'));

//устанавливаем свойства
$mail->setFrom($model->email, $model->name);
$mail->setSubject("Письмо с сайта loco.ru: ".$model->subject);
$mail->setTo(Yii::app()->params['adminEmail']);

//Сохраняем загруженные файлы на сервер нашей функцией uploadMultifile
 if($filez=$this->uploadMultifile($model,'attachments','/tmp/attachments/'))
   {
$model->attachments=implode(",", $filez);
   }

//Прикрепляем к сообщению загруженные файлы с помощью setAttachment() 
$attachments = explode(',', $model->attachments);
        if (count($attachments)) {
            foreach ($attachments as $file) {
                $mail->setAttachment('tmp/attachments/'.$file);
            }
        }

//отправляем сообщение
if ($mail->send()) {
Yii::app()->user->setFlash('contact','Спасибо за ваше письмо! Мы ответим вам в ближайшее время.');
Yii::app()->getController()->createAction('captcha')->getVerifyCode(true);
} else {
Yii::app()->user->setFlash('error','Какая-то ошибка: '.$mail->getError());
}

$this->refresh();
}
}
$this->render('contact',array('model'=>$model));
} 


public function uploadMultifile ($model,$attr,$path)
{
/*
* path when uploads folder is on site root.
* $path='/tmp/attachments/'
*/
if($sfile=CUploadedFile::getInstances($model, $attr)){
 foreach ($sfile as $i=>$file){  
    $formatName=time().$i.'.'.$file->getExtensionName();
    $file->saveAs(Yii::app()->basePath .DIRECTORY_SEPARATOR.'..'. $path.$formatName);
    $ffile[$i]=$formatName;
  }
  return ($ffile);
 }
}
...
person almix    schedule 06.10.2014