symfony2项目上的Swiftmailer附件错误(无法打开文件进行读取)

时间:2016-09-07 07:21:32

标签: php forms symfony email swiftmailer

我正在开发一个symfony项目,我有一个表格必须用swiftmailer发送邮件。 对于说明 - >用户可以使用表单在optionnal文件的上传功能中使用附件。 (表单保存在bdd like命令中,我们在提交表单后有一个回顾,以及3个邮件(每次我们不使用附件工作的两个邮件,只有带有atachment选项的邮件当我们失败)有一个要加入的文件,否则如果我们只使用一个评论(其他字段选项,像路径一样工作,邮件正在工作)

我希望我的解释清楚易懂,我的英语不完美,功能也不太容易。一些信息保密的原因我只在这里写了关注邮件的代码,但如果我忘记了什么只是告诉我,我更新帖子。

当我发送没有附件的邮件时,我没有任何问题,但是当我尝试加入文件时,symfony会给我这个错误:

  

无法打开文件阅读[uploads / 6M.jpg]

我试图在StackOverflow中的其他帖子上获得解决方案,但没有人工作。所以我希望你能帮助我。希望。

命令实体(我已经把关注文件,路径和上传的代码放在附件中(邮件的其余部分和代码工作):     

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Form\Extension\HttpFoundation;

/**
* Commandes
*/
class Commandes
{
// CUSTOM CODE

/**
 * @var string
 */
public $file3;

/**
 * @var string
 */
protected $path3;

public function getAbsolutePath1()
{
    return null === $this->path1 ? null : $this->getUploadRootDir().'/'.$this->id.'.'.$this->path1;
}

public function getWebPath1()
{
    return null === $this->path1 ? null : $this->getUploadDir().'/'.$this->path1;
}

protected function getUploadRootDir()
{
    return __DIR__ . '/../../../web/' . $this->getUploadDir();
}


protected function getUploadDir()
{
    return 'uploads';
}


/**
 * @var string
 */
protected $path1;


/**
 * @Assert\File(maxSize="60000000")
 */
public $file1;


// CallBack : preUpdate | prePersist \\
public function preUpload1()
{
    if (null !== $this->file1) {
        $this->path1 = $this->file1->guessExtension();
    }
}


// CallBacks : PostPersist | PostUpdate \\
public function upload1()
{
    if (null === $this->file1) {
        return;
    }

    $this->file1->move($this->getUploadRootDir(), $this->getReferencePatient() . 'M.' . $this->file1->guessExtension());

    $this->path1 = $this->getReferencePatient() . 'M.' . $this->file1->getClientOriginalExtension();

    $this->file1 = null;
}


protected $path2;

public $file2;

// CallBack : preUpdate | prePersist \\
public function preUpload2()
{
    if (null !== $this->file2) {
        $this->path2 = $this->file2->guessExtension();
    }
}


// CallBacks : PostPersist | PostUpdate \\
public function upload2()
{
    if (null === $this->file2) {
        return;
    }

    $this->file2->move($this->getUploadRootDir(), $this->getReferencePatient() . 'm.' . $this->file2->guessExtension());

    $this->path2 = $this->getReferencePatient() . 'm.' . $this->file2->getClientOriginalExtension();

    $this->file2 = null;
}


public function getAbsolutePath2()
{
    return null === $this->path2 ? null : $this->getUploadRootDir() . '/' . $this->path2;
}

public function getWebPath2()
{
    return null === $this->path2 ? null : $this->getUploadDir() . '/' . $this->path2;
}


// CallBack : preUpdate | prePersist \\
public function preUpload3()
{
    if (null !== $this->file3) {
        $this->path3 = $this->file3->guessExtension();
    }
}

public function upload3()
{
    if (null === $this->file3) {
        return;
    }

    $this->file3->move($this->getUploadRootDir(), $this->getReferencePatient() . '.' . $this->file3->guessExtension());

    $this->path3 = $this->getReferencePatient() . '.' . $this->file3->getClientOriginalExtension();

    $this->file3 = null;
}

public function getAbsolutePath3()
{
    return null === $this->path3 ? null : $this->getUploadRootDir() . '/' . $this->path3;
}

public function getWebPath3()
{
    return null === $this->path3 ? null : $this->getUploadDir() . '/' . $this->path3;
}

/**
 * Set pathPJ1
 *
 * @param string $pathPJ1
 * @return Commandes
 */
public function setPathPJ1($pathPJ1)
{
    $this->pathPJ1 = $pathPJ1;

    return $this;
}

/**
 * Get pathPJ1
 *
 * @return string
 */
public function getPathPJ1()
{
    return $this->pathPJ1;
}

/**
 * Set pathPJ2
 *
 * @param string $pathPJ2
 * @return Commandes
 */
public function setPathPJ2($pathPJ2)
{
    $this->pathPJ2 = $pathPJ2;

    return $this;
}

/**
 * Get pathPJ2
 *
 * @return string
 */
public function getPathPJ2()
{
    return $this->pathPJ2;
}

/**
 * Set pathPJ3
 *
 * @param string $pathPJ3
 * @return Commandes
 */
public function setPathPJ3($pathPJ3)
{
    $this->pathPJ3 = $pathPJ3;

    return $this;
}

/**
 * Get pathPJ3
 *
 * @return string
 */
public function getPathPJ3()
{
    return $this->pathPJ3;
}

/**
 * Set path1
 *
 * @param string $path1
 * @return Commandes
 */
public function setPath1($path1)
{
    $this->path1 = $path1;

    return $this;
}

/**
 * Get path1
 *
 * @return string
 */
public function getPath1()
{
    return $this->path1;
}

/**
 * Set path2
 *
 * @param string $path2
 * @return Commandes
 */
public function setPath2($path2)
{
    $this->path2 = $path2;

    return $this;
}

/**
 * Get path2
 *
 * @return string
 */
public function getPath2()
{
    return $this->path2;
}

/**
 * Set path3
 *
 * @param string $path3
 * @return Commandes
 */
public function setPath3($path3)
{
    $this->path3 = $path3;

    return $this;
}

/**
 * Get path3
 *
 * @return string
 */
public function getPath3()
{
    return $this->path3;
}

指挥控制器(同样我只放了关于附件的代码):

use Symfony\Component\HttpFoundation\Request;
use OrthoBundle\Entity\Compteur;
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use OrthoBundle\Entity\Commandes;
use OrthoBundle\Form\Type\CommandesType;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\Session;

class FormulaireController extends Controller
{
    public function createFormulaireAction(Request $request)
    {   
        $em = $this->getDoctrine()->getManager();

       $commande = new Commandes();

        $request = $this->get('request');

        $user = $this->getUser();

        $form = $this->createForm(new CommandesType($user), $commande);

        if ($form->isValid() && $form->isSubmitted()) {

        ***""""""SOME CODE THAT I DON'T PUT ABOUT PERSIST FLUSH THE COMMAND IN DB""""***

       $message = \Swift_Message::newInstance()
            ->setSubject('Commande n°' . $commande->getId())
            ->setFrom(array('mymail@example.com' => 'send from'))
            ->setTo(array('onemail@example.com' => 'destinatory'))
            ->setCharset('utf-8')
            ->setContentType('text/html')
            ->setBody($this->renderView('@Ortho/Mail/mail_impress.html.twig', array(
                'parentUser' => $user->getParent(),
                'commande' => $commande,
            )));
        if ($commande->getWebPath1() != '') {
            $message->attach(\Swift_Attachment::fromPath($commande->getWebPath1()));
        }
        if ($commande->getWebPath2() != '') {
            $message->attach(\Swift_Attachment::fromPath($commande->getWebPath2()));
        }
        if ($commande->getWebPath3() != '') {
            $message->attach(\Swift_Attachment::fromPath($commande->getWebPath3()));
        }
        if ($commande->getWebPath1() != '' or
            $commande->getWebPath2() != '' or
            $commande->getWebPath3() != '' or
            $commande->getCommentaire() != '') {
            $this->get('mailer')->send($message);              
        }

此代码适用于没有附件的邮件,但如果我尝试在表单上传邮件,则不会。有关信息:文件的上传工作和上传的文件保存在MyApp / web / uploads中。

CommandeType.php:

<?php

namespace MyBundle\Form\Type;

use MyBundle\Entity\Utilisateurs;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Doctrine\ORM\EntityRepository;

class CommandesType extends AbstractType
{
private $user;

public function __construct(Utilisateurs $utilisateurs)
{
    $this->user = $utilisateurs;
}
/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('commentaireLabo', TextareaType::class, array(
            'attr' => array(
                'placeholder' => 'Select a product'
            ),
        ))
        ->add('file1', FileType::class, array(
            'required' => false
        ))
        ->add('file2', FileType::class, array(
            'required' => false
        ))
        ->add('file3', FileType::class, array(
            'required' => false
        ))
        ->add('commentairePrestataire', TextareaType::class, array(
            'required' => false
        ));
}

/**
 * @param OptionsResolver $resolver
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'MyBundle\Entity\Commandes'

    ));
}

}

这里是视图中有关文件的部分:

<fieldset class="smallbloc"> <!-- Bloc n°3 : Les pièces jointes -->
    <h2 class="fs-title">Pièces jointes complémentaires</h2>
    <h3 class="fs-subtitle">Toutes les pièces jointes à apporter à la commande.</h3>

    {{ form_label(form.file1, "Arcade Maxilaire :") }}
    {{ form_errors(form.file1) }}
    {{ form_widget(form.file1) }}

    {{ form_label(form.file2, "Arcade Mandibulaire :") }}
    {{ form_errors(form.file2) }}
    {{ form_widget(form.file2) }}

    {{ form_label(form.file3, "Autre pièces jointe :") }}
    {{ form_errors(form.file3) }}
    {{ form_widget(form.file3) }}

    {{ form_label(form.commentairePrestataire3D, "Commentaires pour le prestataire 3D :") }}
    {{ form_errors(form.commentairePrestataire3D) }}
    {{ form_widget(form.commentairePrestataire3D) }}

    <input type="hidden" id="monthstat" name="monthstat" value="{{ "now"|date("m-Y") }}">

    <input type="button" name="previous" class="previous action-button" value="Précédent"/>
    <input type="submit" name="previous" class="action-button" value="ENVOYER"/>

    {{ form_rest(form) }}
</fieldset>

我希望每个必要的代码都在这里,并且我没有忘记一些东西,如果不是只是说,我将要更新我的帖子,并添加mising部分。或者,如果我说了一些无脑或者不可理解的东西,只是说我解释。我知道阅读x)并不容易。谢谢你们每个人的帮助。

2 个答案:

答案 0 :(得分:2)

附加文件时,您必须使用文件系统的绝对路径,例如:

$message->attach(\Swift_Attachment::fromPath($commande->getAbsolutePath1()));

SwiftMailer 运行&#34;服务器端&#34;,它无法访问您的前端以获取您要附加到邮件中的文件。

  

PS:您可能还想检查您的文件实际是否存在于应该存在的目录中。也许上传没有按预期工作,文件不存在

答案 1 :(得分:0)

我有同样的问题,这是因为地址使用错误

$this->container->get("kernel")->getRootDir()."/../public/".$attac

其中$ attac是您在公共目录中的附件文件地址 我使用Symfony flex版本4