mirror of
https://github.com/wallabag/wallabag.git
synced 2024-12-22 23:56:29 +00:00
Fix the way to remove a tag from all user entries
This commit is contained in:
parent
1bb1939ab7
commit
4059a061c0
3 changed files with 53 additions and 10 deletions
|
@ -310,5 +310,12 @@ class WallabagRestControllerTest extends WallabagApiTestCase
|
||||||
$this->assertArrayHasKey('label', $content);
|
$this->assertArrayHasKey('label', $content);
|
||||||
$this->assertEquals($tag['label'], $content['label']);
|
$this->assertEquals($tag['label'], $content['label']);
|
||||||
$this->assertEquals($tag['slug'], $content['slug']);
|
$this->assertEquals($tag['slug'], $content['slug']);
|
||||||
|
|
||||||
|
$entries = $entry = $this->client->getContainer()
|
||||||
|
->get('doctrine.orm.entity_manager')
|
||||||
|
->getRepository('WallabagCoreBundle:Entry')
|
||||||
|
->findAllByTagId($this->user->getId(), $tag['id']);
|
||||||
|
|
||||||
|
$this->assertCount(0, $entries);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,11 @@ abstract class WallabagApiTestCase extends WebTestCase
|
||||||
*/
|
*/
|
||||||
protected $client = null;
|
protected $client = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \FOS\UserBundle\Model\UserInterface
|
||||||
|
*/
|
||||||
|
protected $user;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
$this->client = $this->createAuthorizedClient();
|
$this->client = $this->createAuthorizedClient();
|
||||||
|
@ -31,8 +36,8 @@ abstract class WallabagApiTestCase extends WebTestCase
|
||||||
$loginManager = $container->get('fos_user.security.login_manager');
|
$loginManager = $container->get('fos_user.security.login_manager');
|
||||||
$firewallName = $container->getParameter('fos_user.firewall_name');
|
$firewallName = $container->getParameter('fos_user.firewall_name');
|
||||||
|
|
||||||
$user = $userManager->findUserBy(array('username' => 'admin'));
|
$this->user = $userManager->findUserBy(array('username' => 'admin'));
|
||||||
$loginManager->loginUser($firewallName, $user);
|
$loginManager->loginUser($firewallName, $this->user);
|
||||||
|
|
||||||
// save the login token into the session and put it in a cookie
|
// save the login token into the session and put it in a cookie
|
||||||
$container->get('session')->set('_security_'.$firewallName, serialize($container->get('security.token_storage')->getToken()));
|
$container->get('session')->set('_security_'.$firewallName, serialize($container->get('security.token_storage')->getToken()));
|
||||||
|
|
|
@ -183,19 +183,50 @@ class EntryRepository extends EntityRepository
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a tag from all user entries.
|
* Remove a tag from all user entries.
|
||||||
* We are using a native SQL query because Doctrine doesn't know EntryTag entity because it's a ManyToMany relation.
|
*
|
||||||
* Instead of that SQL query we should loop on every entry and remove the tag, could be really long ...
|
* We need to loop on each entry attached to the given tag to remove it, since Doctrine doesn't know EntryTag entity because it's a ManyToMany relation.
|
||||||
|
* It could be faster with one query but I don't know how to retrieve the table name `entry_tag` which can have a prefix.
|
||||||
*
|
*
|
||||||
* @param int $userId
|
* @param int $userId
|
||||||
* @param Tag $tag
|
* @param Tag $tag
|
||||||
*/
|
*/
|
||||||
public function removeTag($userId, Tag $tag)
|
public function removeTag($userId, Tag $tag)
|
||||||
{
|
{
|
||||||
$sql = 'DELETE et FROM entry_tag et WHERE et.entry_id IN ( SELECT e.id FROM entry e WHERE e.user_id = :userId ) AND et.tag_id = :tagId';
|
$entries = $this->getBuilderByUser($userId)
|
||||||
$stmt = $this->getEntityManager()->getConnection()->prepare($sql);
|
->innerJoin('e.tags', 't')
|
||||||
$stmt->execute([
|
->andWhere('t.id = :tagId')->setParameter('tagId', $tag->getId())
|
||||||
'userId' => $userId,
|
->getQuery()
|
||||||
'tagId' => $tag->getId(),
|
->getResult();
|
||||||
]);
|
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$entry->removeTag($tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->getEntityManager()->flush();
|
||||||
|
|
||||||
|
// An other solution can be to use raw query but I can't find a way to retrieve the `entry_tag` table name since it can be prefixed....
|
||||||
|
// $sql = 'DELETE et FROM entry_tag et WHERE et.entry_id IN ( SELECT e.id FROM entry e WHERE e.user_id = :userId ) AND et.tag_id = :tagId';
|
||||||
|
// $stmt = $this->getEntityManager()->getConnection()->prepare($sql);
|
||||||
|
// $stmt->execute([
|
||||||
|
// 'userId' => $userId,
|
||||||
|
// 'tagId' => $tag->getId(),
|
||||||
|
// ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all entries that are attached to a give tag id.
|
||||||
|
*
|
||||||
|
* @param int $userId
|
||||||
|
* @param int $tagId
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function findAllByTagId($userId, $tagId)
|
||||||
|
{
|
||||||
|
return $this->getBuilderByUser($userId)
|
||||||
|
->innerJoin('e.tags', 't')
|
||||||
|
->andWhere('t.id = :tagId')->setParameter('tagId', $tagId)
|
||||||
|
->getQuery()
|
||||||
|
->getResult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue