Sonata User Bundle Avatar 使用 Sonata Media Bundle,以自定义形式更新图像更新旧图像,同时创建新图像

Sonata User Bundle Avatar using Sonata Media Bundle, in custom form while update image updates old one, and also creating a new one

我正在使用 Sonata Media Bundle 在 Sonata User Bundle avatar 中工作。在 Sonata Admin(后端)中,一切都按预期工作。即在更新表单管理时,只有旧文件被替换。(效果很好)。

问题: 尝试在前端通过自定义表单编辑用户个人资料时。图像正确上传并替换了旧图像,但它另外在文件夹中创建了一个新图像,也在媒体中创建了一个新条目。仅将新图像 ID 添加到用户条目(头像),而不是旧图像 ID。通常只会使用旧的。

我需要的是edit/update旧图像而不是添加新图像&条目。

提示: 文件夹权限良好 - 因为它可以编辑旧文件。

问题的预期解决方案:如何新建条目?而不是 edit/update.!

User.php

namespace Application\Sonata\UserBundle\Entity;
// all use ... i deleted to reduce lines
/**
* @ORM\Table(name="fos__user_user")
* @ORM\Entity()
* @ORM\HasLifecycleCallbacks()
* @Assert\Callback(methods={ "isMediaSizeValid" })
*/
class User extends BaseUser {

/**
 * @var string
 *
 * @ORM\OneToOne(targetEntity="Application\Sonata\MediaBundle\Entity\Media",cascade={"persist"} )
 * @ORM\JoinColumns( { @ORM\JoinColumn( referencedColumnName="id", onDelete="CASCADE" ) } )
 * @Assert\NotNull()
 */
private $profilePicture;

// generated getter and setter
  public function setProfilePicture(\Application\Sonata\MediaBundle\Entity\Media $profilePicture = null) {
    $this->profilePicture = $profilePicture;
    return $this;
  }
  public function getProfilePicture() {
    return $this->profilePicture;
  }

  public function isMediaSizeValid(ExecutionContextInterface $context) {
    $this->fzValidateImage($context, $this->getProfilePicture());
  }

  private function fzValidateImage($context, $f) {
    if ($f == NULL) {
        // IMAGE can be null . If null it uses the default image             
    } else if ($f->getSize() > (self::FILE_SIZE * 1024)) {
        $context->buildViolation('The file is too large ( %a% kb). Allowed maximum size is %b% kb.')->atPath(self::FILE_PATH)->setParameters(['%a%' => intval($f->getSize() / 1024), '%b%' => self::FILE_SIZE])->addViolation();
    } else if ($f->getWidth() < self::FILE_MIN_WIDTH) {
        $context->buildViolation('The image width is too small ( %a% px). Minimum width expected is  %b% px.')->atPath(self::FILE_PATH)->setParameters(['%a%' => $f->getWidth(), '%b%' => self::FILE_MIN_WIDTH])->addViolation();
    } else if ($f->getWidth() > self::FILE_MAX_WIDTH) {
        $context->buildViolation('The image width is too big ( %a% px). Allowed maximum width is  %b% px.')->atPath(self::FILE_PATH)->setParameters(['%a%' => $f->getWidth(), '%b%' => self::FILE_MAX_WIDTH])->addViolation();
    } else if ($f->getHeight() < self::FILE_MIN_HEIGHT) {
        $context->buildViolation('The image height is too small ( %a% px). Minimum height expected is  %b% px.')->atPath(self::FILE_PATH)->setParameters(['%a%' => $f->getHeight(), '%b%' => self::FILE_MIN_HEIGHT])->addViolation();
    } else if ($f->getHeight() > self::FILE_MAX_HEIGHT) {
        $context->buildViolation('The image height is too big ( %a% px). Allowed maximum height is  %b% px.')->atPath(self::FILE_PATH)->setParameters(['%a%' => $f->getHeight(), '%b%' => self::FILE_MAX_HEIGHT])->addViolation();
    }
  }
}

UserController.php 类型 1

    /**
     * @Route("/profile/edit", name="fz_user_profile_edit")
     */
    public function editProfileAction(Request $request) {
        $form = $this->get('sonata.user.profile.form');
        $form->add('profilePicture', 'sonata_media_type', array(
            'provider' => 'sonata.media.provider.image',
            'context' => 'profile'
        ));
        $form->get('profilePicture')->add('binaryContent', 'file', ['label' => 'Profile Picture']);
        $form->get('profilePicture')->remove('unlink');
        $formHandler = $this->get('sonata.user.profile.form.handler');

        $process = $formHandler->process($user);
        if ($process) {
            $this->setFlash('notice', 'Profile updated!');
            return $this->redirectToRoute('fz_user');
        }
        $x = ['cmf' => '', 'pTitle' => 'Profile'];
        return $this->render('user/layout.html.twig', ['x' => $x, 'form' => $form->createView()]);

UserController.php 类型 2

/**
 * @Route("/profile/edit", name="fz_user_profile_edit")
 */
public function editProfileAction(Request $request) {
    $user = $this->getUser();
    if (!is_object($user) || !$user instanceof UserInterface) {
        throw $this->createAccessDeniedException('This user does not have access to this section.');
    }
    $builder = $this->createFormBuilder($user);
    $builder->add('profilePicture', 'sonata_media_type', array(
        'provider' => 'sonata.media.provider.image',
        'context' => 'profile'
    ));
    $form = $builder->getForm();
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($user);
        $em->flush();
        $this->setFlash('notice', 'Profile updated!');
    }

    $x = ['cmf' => '', 'pTitle' => 'Profile'];
    return $this->render('user/layout.html.twig', ['x' => $x, 'form' => $form->createView()]);
}

UserController.php 类型 1 - 代码正在使用 FOSUserBundle。和 UserController.php 输入 2 我的 symfony 文档自定义代码..

我现在通过检查文件并删除来解决。我认为这是一个捆绑包错误。

public function editProfileAction() {
    $user = $this->getUser();
    if (!is_object($user) || !$user instanceof UserInterface) {
        throw $this->createAccessDeniedException('This user does not have access to this section.');
    }
    // Check user has allready media?
    $om = $this->getUser()->getProfilePicture();
    $oldPath = $om ? $this->getMediaPath($om->getId()) : NULL;
    $form = $this->creteForm();
    $formHandler = $this->get('sonata.user.profile.form.handler');
    $process = $formHandler->process($user);
    if ($process) {
        // if new file - delete old file
        $this->deleteOldMedia($om, $oldPath);
        $this->setFlash('notice', 'Profile updated!');
        return $this->redirectToRoute('fz_user');
    }
    $x = ['cmf' => '', 'pTitle' => 'Profile'];
    return $this->render('user/layout.html.twig', ['x' => $x, 'form' => $form->createView()]);
}

private function getMediaPath($id) {
    $mm = $this->container->get('sonata.media.manager.media');
    $pr = $this->container->get('sonata.media.provider.image');
    $media = $mm->findOneBy(['id' => $id]);
    $format = $pr->getFormatName($media, 'reference');
    return $pr->generatePublicUrl($media, $format);
}

protected function creteForm() {
    $form = $this->get('sonata.user.profile.form');
    $form->add('profilePicture', 'sonata_media_type', array(
        'provider' => 'sonata.media.provider.image',
        'context' => 'profile',
        'new_on_update' => FALSE
    ));
    $form->get('profilePicture')->add('binaryContent', 'file', ['label' => 'Profile Picture', 'required' => FALSE]);
    $form->get('profilePicture')->remove('unlink');
    return $form;
}

private function deleteOldMedia($om, $oldPath) {
    if ($om) {
        $newPath = $this->getMediaPath($this->getUser()->getProfilePicture()->getId());
        if ($newPath && ($oldPath != $newPath)) {
            $dir = $this->container->getParameter('kernel.root_dir');
            $file = $dir . '/../public_html/' . $oldPath;
            $i = file_exists($file) ? unlink($file) : NULL;
            return $i;
        }
    }
}