2017-07-26 68 views
0

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); 
} 

}

視圖 - 枝 - 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

這些產品與用戶的實體「關聯」嗎?如通過在用戶實體上的加入?你的數據庫是否強制執行任何FK約束? – ficuscr

+0

FK約束被刪除 - 我附加了用戶實體 – RKlina

回答

1

好了,我沒有看到用戶實體與這些產品之間的關係。

您可以爲用戶對產品設置一對一(xref/join table /無論您稱之爲什麼),並讓Doctrine爲您處理它。

/** 
    * @var Collection 
    * @OneToMany(targetEntity="UserProductsXref",mappedBy="user", cascade= 
{"persist","remove"}) 
    */ 
private $products; 
} 

或者,繼續看似你的意圖。啓動某些存儲庫方法並以編程方式刪除關聯的行。什麼不適合你的方法使用deleteAllProductsByVendorId()