У меня есть форма со встроенной формой файла (коллекция News и NewsFiles). На моей локальной машине все работает нормально: сущности News и NewsFiles сохраняются, файлы загружаются.
Но на рабочем сервере почтовый запрос останавливается, когда я пытаюсь добавить файл. Файлы загружены, сущности не существуют в БД, пост-запрос останавливается со статусом: 302 Найдено и возвращает пустую страницу вместо перенаправления на следующую страницу.
public function createAction(Request $request) {
$entity = new News();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
// PROBLEM APPEARS HERE - WHEN TRY TO FLUSH
$em->flush();$this->get('session')->getFlashBag()->add(
'success', 'Wykonano pomyślnie!'
);
return $this->redirect($this->generateUrl('website_admin_panel_news'));
}
return $this->render('WebsiteNewsBundle:News:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
Нет проблем при попытке добавить только сущность News (без файлов). То же самое, когда я редактирую сущность.
ЖУРНАЛЫ:
бревна
INFO - Matched route "news_update" (parameters: "_controller": "Website\NewsBundle\Controller\NewsController::updateAction", "id": "6", "_route": "news_update")
DEBUG - Read SecurityContext from the session
DEBUG - Reloading user from user provider.
DEBUG - Username "admin" was reloaded from user provider.
DEBUG - Write SecurityContext in the session
Я думаю, что проблема на стороне сервера, я напишу администратору, но он не эксперт, поэтому я должен предложить ему, что он должен изменить … Есть идеи? Может ли это быть проблемой тайм-аутов?
Редактировать:
У меня есть больше информации. Проблема возникает в функции move (). Это не проблема с тайм-аутами, потому что я пытался отправить небольшой файл (1px — 539 байт), и он все еще не выполняет свою работу.
Вот мой объект для загрузки:
<?php
namespace Website\NewsBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
// use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints;
/**
*
*
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
* @ORM\Table(name="NewsFiles")
*
*/
class NewsFile {
private $temp;
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*
*/
private $owner;
/**
*
*/
private $file;
/**
* @ORM\Column(type="string", length=255)
*
*/
private $name;
/**
* @ORM\Column(type="datetime")
*/
private $created_at;
/**
* @ORM\ManyToOne(targetEntity="News", inversedBy="newsFiles")
* @ORM\JoinColumn(name="news_id", referencedColumnName="id")
*/
protected $news;
/**
* @var string
*
* @ORM\Column(name="path", type="string", length=255)
*/
private $path;
/**
* @var string
*
* @ORM\Column(type="boolean", nullable=false)
*/
private $isMain;
/**
* Now we tell doctrine that before we persist or update we call the updatedTimestamps() function.
*
* @ORM\PrePersist
* @ORM\PreUpdate
*/
public function updatedTimestamps() {
if ($this->getCreated_At() == null) {
$this->setCreated_At(new \DateTime(date('Y-m-d H:i:s')));
}
}
public function setId($id) {
$this->id = $id;
}
public function getId() {
return $this->id;
}
public function setOwner($owner) {
$this->owner = $owner;
}
public function getOwner() {
return $this->owner;
}
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function setPath($path) {
$this->path = $path;
}
public function getPath() {
return $this->path;
}
/**
* Set created_at
*
* @param string $created_at
* @return File
*/
public function setCreated_at($created_at) {
$this->created_at = $created_at;
return $this;
}
/**
* Get created_at
*
* @return string
*/
public function getCreated_at() {
return $this->created_at;
}
/**
* Sets file.
*
* @param UploadedFile $file
*/
public function setFile(UploadedFile $file = null) {
$this->file = $file;
// check if we have an old image path
if (isset($this->path)) {
// store the old name to delete after the update
$this->temp = $this->path;
$this->path = null;
} else {
$this->path = 'initial';
}
}
/**
* Get file.
*
* @return UploadedFile
*/
public function getFile() {
return $this->file;
}
public function getAbsolutePath() {
return null === $this->path ? null : $this->getUploadRootDir() . '/' . $this->path;
}
public function getWebPath() {
return null === $this->path ? null : $this->getUploadDir() . '/' . $this->path;
}
protected function getUploadRootDir() {
// the absolute directory path where uploaded documents should be saved
return __DIR__ . '/../../../../web/' . $this->getUploadDir();
}
protected function getUploadDir() {
return 'uploads/News/' . $this->getNews()->getId();
}
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload() {
if (null !== $this->file) {
// zrób cokolwiek chcesz aby wygenerować unikalną nazwę
$this->setName(sha1(uniqid(mt_rand(), true)));
$this->setPath($this->getName() . '.' . $this->file->guessExtension());
}
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload() {
// zmienna file może być pusta jeśli pole nie jest wymagane
if (null === $this->file) {
return;
}
// HERE HE CANCEL HIS WORK
$this->getFile()->move($this->getUploadRootDir(), $this->path);// check if we have an old image
if (isset($this->temp)) {
echo "isset temp";
// delete the old image
unlink($this->getUploadRootDir() . '/' . $this->temp);
// clear the temp image path
$this->temp = null;
}
$this->file = null;
}
/**
* @ORM\PostRemove()
*/
public function removeUpload() {
if ($file = $this->getAbsolutePath()) {
unlink($file);
}
}
/**
* Set news
*
* @param string $news
* @return News
*/
public function setNews($news) {
$this->news = $news;
return $this;
}
/**
* Get news
*
* @return string
*/
public function getNews() {
return $this->news;
}
/**
* Set isMain
*
* @param string $isMain
* @return IsMain
*/
public function setIsMain($isMain) {
$this->isMain = $isMain;
return $this;
}
/**
* Get isMain
*
* @return string
*/
public function getIsMain() {
return $this->isMain;
}
}
Хорошо, я обнаружил, что происходит.
Мой prod сервер не принимает функцию chmod, он заблокирован. Файл Symfony2:
/vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/File/UploadedFile.php
есть функция move () -> я там удалил использование chmod и все работает нормально.
Вот функция move () после модификации:
public function move($directory, $name = null)
{
if ($this->isValid()) {
if ($this->test) {
return parent::move($directory, $name);
}
$target = $this->getTargetFile($directory, $name);
if (!@move_uploaded_file($this->getPathname(), $target)) {
$error = error_get_last();
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message'])));
}
return $target;
}
throw new FileException($this->getErrorMessage());
}
Других решений пока нет …