如何将呈现的内容写入文件

时间:2014-03-14 15:07:55

标签: file symfony

我想要渲染内容,例如$this->render('ProBundle:Default:view.html.twig', array('data' => $data));,并将其写入文件。

我已经创建了一个文件类:

<?php

namespace Pro\ConvocationBundle\Entity;

use Symfony\Component\HttpFoundation\File\File as SymfonyFile;
use Symfony\Component\Validator\Constraints;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="file")
 */
class File
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column
     * @Constraints\NotBlank
     */
    private $name;

    /**
     * @var \DateTime
     * @ORM\Column(type="datetime")
     * @Constraints\NotNull
     * @Constraints\DateTime
     */
    private $created;

    /**
     * @var SymfonyFile
     * @Constraints\File(maxSize=1048060)
     */
    private $filesystemFile;

    /**
     * @Constraints\NotNull
     * @ORM\OneToOne(targetEntity="Pro\ConvocationBundle\Entity\Convocation")
     * @ORM\JoinColumn(nullable=false)
     */
    private $convocation;

    function __construct(SymfonyFile $file, $name)
    {
        $this->created = new \DateTime;
        $this->setFilesystemFile($file);
        $this->name = $name;
    }

    function getId()
    {
        return $this->id;
    }

    function getName()
    {
        return $this->name;
    }

    function getCreated()
    {
        return $this->created;
    }

    function setFilesystemFile(SymfonyFile $file)
    {
        $this->filesystemFile = $file;
    }

    function getFilesystemFile()
    {
        return $this->filesystemFile;
    }
}

和服务:

<?php

namespace Pro\ConvocationBundle\Service;

use Frosas\Error;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Pro\ConvocationBundle\Entity\ConvocationFile as FileEntity;

class ConvocationFile
{
    private $dir;

    function __construct($dir)
    {
        $this->dir = $dir;
    }

    function postLoad(LifecycleEventArgs $args)
    {
        if (($entity = $args->getEntity()) instanceof FileEntity) {
            $filesystemFilePath = $this->getFilesystemPath($entity);
            $filesystemFile = new \Symfony\Component\HttpFoundation\File\File($filesystemFilePath);
            $entity->setFilesystemFile($filesystemFile);
        }
    }

    function postPersist(LifecycleEventArgs $args)
    {
        if (($entity = $args->getEntity()) instanceof FileEntity) {
            $this->saveToFilesystem($entity);
        }
    }

    function postUpdate(LifecycleEventArgs $args)
    {
        if (($entity = $args->getEntity()) instanceof FileEntity) {
            if ($entity->getFilesystemFile()->getPathname() !== $this->getFilesystemPath($entity)) {
                $this->saveToFilesystem($entity);
            }
        }
    }

    function postRemove(LifecycleEventArgs $args)
    {
        if (($entity = $args->getEntity()) instanceof FileEntity) {
            $ok = @unlink($entity->getFilesystemFile());
            if (! $ok) throw Error::createExceptionFromLast();
        }
    }

    private function saveToFilesystem(FileEntity $file)
    {
        $filesystemFile = $file->getFilesystemFile();
        if ($filesystemFile === null) throw new \InvalidArgumentException("No file given");
        if (! $filesystemFile->isFile()) throw new \InvalidArgumentException("File is not a file");

        $path = $this->getFilesystemPath($file);
        $filesystemFile->move(dirname($path), basename($path));
    }

    private function getFilesystemPath(FileEntity $file)
    {
        return "$this->dir/{$file->getId()}";
    }
}

并在配置文件中:

pro_convocation.convocation_file:
    class: Pro\ConvocationBundle\Service\File
    arguments: [%kernel.root_dir%/var/files]
    tags:
        - {name: doctrine.event_listener, event: postLoad}
        - {name: doctrine.event_listener, event: postPersist}
        - {name: doctrine.event_listener, event: postUpdate}
        - {name: doctrine.event_listener, event: postRemove}

所以我猜我可以调用该服务并创建文件:

$newContent = $this->get('templating')->render('ProConvocationBundle:Default:view.html.twig', array('data' => $data));

$this->get('pro_convocation.convocation_file')->postPersist($newContent);

但我收到此错误:

Catchable Fatal Error: Argument 1 passed to Pro\ConvocationBundle\Service\File::postPersist() must be an instance of Doctrine\ORM\Event\LifecycleEventArgs, string given

postPersist接受一个事件对象作为参数,而不是要写入的内容。所以我现在对如何创建新文件感到有点困惑。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

这是因为您尝试将 ConvocationFile 类用作服务。这是一项服务,但并不意味着以这种方式进行调用。这就是为什么该类应该在您的包中的 EventListener 文件夹中,如Symfony2约定所示:

\src\Pro\ConvocationBundle\EventListener\ConvocationFile.php

如果您想手动调用此服务,只要它是一个事件监听器,您就必须发送一个监听器可以捕获的事件。

所以,你应该尝试使用类似的东西:

<?php

use Doctrine\ORM\Events;
use Doctrine\Common\EventManager;

$arguments = array('my_stuff');

$evm = new EventManager();
$evm->dispatchEvent(Events::postUpdate, $arguments);

否则,您可以定义一个处理文件的服务,将它们保存到文件系统,并使您的事件监听器和控制器使用它。

更多信息: