我想要渲染内容,例如$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
接受一个事件对象作为参数,而不是要写入的内容。所以我现在对如何创建新文件感到有点困惑。有什么想法吗?
答案 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);
否则,您可以定义一个处理文件的服务,将它们保存到文件系统,并使您的事件监听器和控制器使用它。
更多信息: