Symfony很新 - 我能够成功删除用户,但是我很难删除与用户关联的所有产品。我的目标是单击管理员后端中的按钮并删除用户以及与该用户关联的所有产品。
我尝试了几种方法,并且在我自己的追求中有点迷失。我恢复了原来的代码,成功地允许我删除用户。
我们将不胜感激。不确定我是否还需要包含VendorRepository。
UserRepository.php
public function delete($id)
{
// get access to the entity manager
$em = $this->getEntityManager();
// get the user from the repository by id
$user = $em->getReference('Thinkfasttoys\Core\Entity\user', $id);
// use built in methods to delete the user
$em->remove($user);
// update the database with the change
$em->flush();
}
ProductRepository.php
public function deleteAllProductsByVendorId($vendorId)
{
// @Todo: revisit this at a later date and determine if the vendor id is actually required
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->delete("Thinkfasttoys\Mapwatch\Entity\Product","p")
->andWhere($qb->expr()->eq('p.vendor', ':vendor'))
->setParameter(':vendor', $vendorId)
->getQuery()
->getResult();
}
public function delete($id)
{
// @Todo: switch to vendor id, instead of user id
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->delete("Thinkfasttoys\Mapwatch\Entity\Product","p")
->andWhere($qb->expr()->eq('p.vendor', ':vendor'))
->setParameter(':vendor', $vendorId)
->getQuery()
->getResult();
}
服务 - Users.php
public function delete($id)
{
$this->repository->delete($id);
}
控制器 - AdminController
/**
* @Route("/admin/user/delete/{id}", name="admin_user_delete")
* @Template
*/
public function deleteAction($id)
{
$dispatcher = $this->container->get('event_dispatcher');
$this->get('users')->delete($id);
// create the user event and dispatch it
$event = new UserEvent($id);
$dispatcher->dispatch(UserEvents::USER_DELETED, $event);
$this->get('session')->getFlashBag()->add('notice-success', 'User deleted successfully.');
return $this->redirect($this->generateUrl('admin_user_list'));
}
实体 - BaseUser.php
class BaseUser
{
/**
* Primary key and id of the record
* @var integer
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*
*/
protected $id;
/**
* Activation code used for the user
* @var string
* @ORM\Column(type="string", nullable=true)
*/
protected $activationCode;
/**
* This should limit the user to specific domain, but should be optional
* @var string
* @ORM\Column(type="string", length=255, nullable=true)
*
*/
protected $domain;
/**
* The email of the user
* @var string
* @ORM\Column(type="string", length=255, nullable=true, unique=true)
* @Assert\NotBlank()
* @Assert\Email()
*/
protected $email;
/**
* @var boolean
* @ORM\Column(type="boolean")
*
*/
protected $enabled;
/**
* The password of the user
* @var string
* @ORM\Column(type="string", nullable=true)
* @Assert\NotBlank()
*/
protected $password;
/**
* The signup code of the user, if any
* @var string
* @ORM\Column(type="string", nullable=true)
* @Assert\NotBlank()
*/
protected $signupCode;
/**
* Date and time when the user requested a password
*
* @var datetime
* @ORM\Column(type="datetime", nullable=true)
*
*/
protected $passwordRequestedAt;
/**
* @ORM\Column(type="array")
* @Assert\NotNull()
*/
protected $roles;
/**
* This is a temporary variable to reference the existing mongodb object,
* once the migration is complete, this can be dropped
*
* @var string
* @ORM\Column(type="string", nullable=true)
*/
protected $mongoUserId;
public function __construct($username = null, $password = null, array $roles = null)
{
$this->email = $username;
$this->password = $password;
if ($roles == null) {
$this->roles = array('ROLE_USER');
} else {
$this->roles = $roles;
}
$this->enabled = false;
}
public function getId()
{
return $this->id;
}
public function getActivationCode() {
return $this->activationCode;
}
public function setActivationCode($activationCode) {
$this->activationCode = $activationCode;
return $this;
}
public function getDomain()
{
return $this->domain;
}
public function setDomain($domain)
{
$this->domain = $domain;
}
public function getEmail()
{
return $this->email;
}
public function setEmail($email)
{
$this->email = $email;
}
public function setEnabled($enabled)
{
$this->enabled = $enabled;
return $this;
}
public function getPassword()
{
return $this->password;
}
public function setPassword($password)
{
$this->password = $password;
}
public function getRoles()
{
return $this->roles;
}
public function setRoles(array $roles)
{
$this->roles = $roles;
}
public function getSignupCode() {
return $this->signupCode;
}
public function setSignupCode($signupCode) {
$this->signupCode = $signupCode;
return $this;
}
public function getUsername()
{
return $this->email;
}
public function getSalt()
{
$salt = strrev(str_replace('@', '_', $this->email));
return $salt;
}
public function eraseCredentials()
{
}
public function equals(UserInterface $user)
{
if (!$user instanceof User) {
return false;
}
if ($this->password !== $user->getPassword()) {
return false;
}
if ($this->getSalt() !== $user->getSalt()) {
return false;
}
if ($this->getUsername() !== $user->getUsername()) {
return false;
}
return true;
}
public function getPasswordRequestedAt() {
return $this->passwordRequestedAt;
}
public function setPasswordRequestedAt($passwordRequestedAt = null) {
$this->passwordRequestedAt = $passwordRequestedAt;
return $this;
}
public function isPasswordRequestNonExpired($ttl)
{
return $this->getPasswordRequestedAt() instanceof \DateTime &&
$this->getPasswordRequestedAt()->getTimestamp() + $ttl > time();
}
public function getPasswordResetCode()
{
$current = '';
if ($this->getPasswordRequestedAt() != null) {
$current = $this->getPasswordRequestedAt()->getTimestamp();
}
return md5($current . ' ' . $this->getEmail());
}
/**
* @return string
*/
public function getMongoUserId()
{
return $this->mongoUserId;
}
/**
* @param string $mongoUserId
*/
public function setMongoUserId($mongoUserId)
{
$this->mongoUserId = $mongoUserId;
}
}
实体 - User.php
class Users
{
protected $repository;
protected $metadata;
protected $userClass;
protected $superUserClass = 'Thinkfasttoys\Core\Entity\SuperUser';
protected $encoder;
protected $mailer;
protected $container;
protected $from_email;
protected $em;
public function __construct($em, $userClass, $mailer, $container)
{
$this->userClass = $userClass;
$this->em = $em;
$this->metadata = $em->getClassMetadata($userClass);
if (false !== strpos($this->userClass, ':')) {
$this->userClass = $this->metadata->name;
}
$this->repository = $this->em->getRepository($userClass);
$this->mailer = $mailer;
$this->container = $container;
$this->from_email = $this->container->getParameter('default_from_address');
}
public function getUser($email)
{
return $this->repository->findOneByEmail($email);
}
public function getUserById($id)
{
return $this->repository->find($id);
}
public function refreshUser(UserInterface $user)
{
if (get_class($user) !== $this->userClass) {
$this->userClass = get_class($user);
$this->repository = $this->em->getRepository($this->userClass);
}
$id = $this->metadata->getIdentifierValues($user);
$user = $this->getUserById($id);
return $user;
}
public function getAllUsers() {
// make sure you only get non super admins
return $this->repository->getAllUsers();
}
public function getAllUsersInArray($userIds) {
// make sure you only get non super admins
return $this->repository->getAllUsersInArray($userIds);
}
public function getAllExistingUserIds() {
// make sure you only get non super admins
return $this->repository->getAllExistingUserIds();
//$existingUserIds = array();
//
//foreach ($results as $user) {
// $existingUserIds[] = $user->getId();
//}
//
//return $existingUserIds;
}
public function getAllUsersByRole($roles) {
// make sure you only get non super admins
return $this->repository->getAllUsersByRole($roles);
}
public function getAllUsersByRoleAsArray($roles) {
// make sure you only get non super admins
return $this->repository->getAllUsersByRoleAsArray($roles);
}
public function getUserClass()
{
return $this->userClass;
}
public function createUser($email, $rawpassword, $roles = array(), $activationCode = null, $signupCode = null, $enabled = false, $domain = null)
{
$class = $this->userClass;
$user = new $class($email, null, array());
$password = $this->createHashPassword($rawpassword, $user->getSalt());
$user->setEmail($email);
$user->setPassword($password);
$user->setRoles($roles);
$user->setActivationCode($activationCode);
$user->setSignupCode($signupCode);
$user->setEnabled($enabled);
$user->setDomain($domain);
$this->repository->save($user);
return $user;
}
public function updateUser($id, $email, $rawPassword, $roles = array(), $activationCode = null, $signupCode = null, $enabled = false)
{
$user = $this->getUserById($id);
$password = $this->createHashPassword($rawPassword, $user->getSalt());
if (!empty($rawPassword)) {
$user->setPassword($password);
}
$user->setEmail($email);
$user->setRoles($roles);
$user->setActivationCode($activationCode);
$user->setSignupCode($signupCode);
$user->setEnabled($enabled);
$this->repository->save($user);
return $user;
}
public function updateUserPassword($id, $rawPassword)
{
$user = $this->getUserById($id);
$password = $this->createHashPassword($rawPassword, $user->getSalt());
if (empty($rawPassword)) {
throw new \Exception("Password Is Blank!");
}
$user->setPassword($password);
$user->setPasswordRequestedAt(null);
$this->repository->save($user);
$this->sendPasswordChangedEmail($user);
return $user;
}
public function enableUser($id, $enabled = true) {
$user = $this->getUserById($id);
$user->setEnabled($enabled);
$this->repository->save($user);
return $user;
}
private function createHashPassword($rawpassword, $salt)
{
$encoder = $this->getEncoder();
return $encoder->encodePassword($rawpassword, $salt);
}
private function getEncoder()
{
if ($this->encoder === null) {
$this->encoder = new MessageDigestPasswordEncoder();
}
return $this->encoder;
}
public function delete($id, $vendorId)
{
$this->repository->delete($id);
}
public function sendActivationEmail($email, $activationCode)
{
$message = \Swift_Message::newInstance()
->setSubject('User Registration Confirmation')
->setFrom($this->from_email)
->setTo($email)
->setBody($this->container->get('templating')->render('CoreUsersBundle:Default:activationEmail.txt.twig', array('email' => $email, 'code' => $activationCode)));
$this->mailer->send($message);
}
public function sendPasswordResetEmail($user)
{
$current = new \DateTime('Now');
$user->setPasswordRequestedAt($current);
$this->repository->save($user);
$message = \Swift_Message::newInstance()
->setSubject('You have requested a password reset')
->setFrom($this->from_email)
->setTo($user->getEmail())
->setBody($this->container->get('templating')->render('CoreUsersBundle:PasswordReset:recoveryEmail.txt.twig', array('hashString' => $user->getPasswordResetCode(), 'email' => $user->getEmail()) ), "text/html");
$this->mailer->send($message);
}
public function sendPasswordChangedEmail($user)
{
// $hashString = md5($current->getTimestamp() . ' ' . $user->getEmail());
$this->em->persist($user);
$this->em->flush();
$message = \Swift_Message::newInstance()
->setSubject('Your password has been changed' )
->setFrom($this->from_email)
->setTo($user->getEmail())
->setBody($this->container->get('templating')->render('CoreUsersBundle:PasswordReset:passwordChanged.txt.twig', array('hashString' => $user->getPasswordResetCode(), 'email' => $user->getEmail()) ), "text/html");
$this->mailer->send($message);
}
}
查看 - twig - list.html.twig
<tbody>
{% for user in users %}
<tr>
<td><a href="{{ path('admin_user_edit', {'id': user.id}) }}">{{ user.email }}</a></td>
<!-- <td>{#{ user.domain }#}</td> -->
<td>
{# @ToDo: There has to be a better way to do this #}
{% for role in user.roles %}
{% if role == 'ROLE_ADMIN' %}Administrator{% endif %}
{% if role == 'ROLE_USER' %}User{% endif %}
{% if role == 'ROLE_VENDOR' %}Vendor{% endif %}
{% if role == 'ROLE_RENTAL' %}Rentals{% endif %}
{% if role|length > 1 and not loop.last %}, {% endif %}
{% endfor %}
</td>
<td>{{ user.isEnabled ? 'Yes' : 'No' }}</td>
<td>
<a class="btn btn-primary" type="button" href="{{ path('admin_user_edit', {id: user.id }) }}"><i class="icon-pencil icon-white pull"></i> Edit</a>
<a {% if not user.isEnabled %}data-toggle="modal" data-url="{{ path('admin_user_resend_activation', {'id': user.id}) }}" href="#modal-send-confirmation"{% endif %} class="{% if user.isEnabled %}disabled{% endif %} send btn btn-small btn-success"><i
class="icon-envelope icon-white"></i> Resend Activation Email</a>
<a data-toggle="modal" data-url="{{ path('admin_user_delete', {'id': user.id}) }}" href="#modal-delete-confirmation" class="delete btn btn-small btn-danger"><i
class="icon-remove icon-white"></i></a>
</td>
</tr>
{% endfor %}
</tbody>
答案 0 :(得分:1)
好的,所以我没有看到用户实体与这些产品之间的关系。
你可以为用户对产品设置一对多(xref / join table /无论你怎么称呼它),然后让Doctrine为你处理它。
/**
* @var Collection
* @OneToMany(targetEntity="UserProductsXref",mappedBy="user", cascade=
{"persist","remove"})
*/
private $products;
}
或者,继续看似你的意图。触发某些存储库方法并以编程方式删除关联的行。使用deleteAllProductsByVendorId()
的方法究竟与您的方法无关?