diff options
author | Kévin Gomez <contact@kevingomez.fr> | 2015-10-24 15:11:06 +0200 |
---|---|---|
committer | Kévin Gomez <contact@kevingomez.fr> | 2015-11-11 16:27:19 +0100 |
commit | 625acf335298186b4ff983f9321900d1238e854b (patch) | |
tree | bc3149d9cee320429475ced6a1cb8b53c71ad7eb /src/Wallabag | |
parent | cad8cda7af06234a63b86253da1d813e7b0fd0f2 (diff) | |
download | wallabag-625acf335298186b4ff983f9321900d1238e854b.tar.gz wallabag-625acf335298186b4ff983f9321900d1238e854b.tar.zst wallabag-625acf335298186b4ff983f9321900d1238e854b.zip |
Add a command to automatically tag all entries for a user
Diffstat (limited to 'src/Wallabag')
6 files changed, 142 insertions, 8 deletions
diff --git a/src/Wallabag/CoreBundle/Command/TagAllCommand.php b/src/Wallabag/CoreBundle/Command/TagAllCommand.php new file mode 100644 index 00000000..2cf3f808 --- /dev/null +++ b/src/Wallabag/CoreBundle/Command/TagAllCommand.php | |||
@@ -0,0 +1,66 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Command; | ||
4 | |||
5 | use Doctrine\ORM\NoResultException; | ||
6 | use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; | ||
7 | use Symfony\Component\Console\Input\InputArgument; | ||
8 | use Symfony\Component\Console\Input\InputInterface; | ||
9 | use Symfony\Component\Console\Output\OutputInterface; | ||
10 | |||
11 | class TagAllCommand extends ContainerAwareCommand | ||
12 | { | ||
13 | protected function configure() | ||
14 | { | ||
15 | $this | ||
16 | ->setName('wallabag:tag:all') | ||
17 | ->setDescription('Tag all entries using the tagging rules.') | ||
18 | ->addArgument( | ||
19 | 'username', | ||
20 | InputArgument::REQUIRED, | ||
21 | 'User to tag entries for.' | ||
22 | ) | ||
23 | ; | ||
24 | } | ||
25 | |||
26 | protected function execute(InputInterface $input, OutputInterface $output) | ||
27 | { | ||
28 | try { | ||
29 | $user = $this->getUser($input->getArgument('username')); | ||
30 | } catch (NoResultException $e) { | ||
31 | $output->writeln(sprintf('<error>User %s not found.</error>', $input->getArgument('username'))); | ||
32 | |||
33 | return 1; | ||
34 | } | ||
35 | $tagger = $this->getContainer()->get('wallabag_core.rule_based_tagger'); | ||
36 | |||
37 | $output->write(sprintf('Tagging entries for user « <info>%s</info> »... ', $user->getUserName())); | ||
38 | |||
39 | $entries = $tagger->tagAllForUser($user); | ||
40 | |||
41 | $em = $this->getDoctrine()->getManager(); | ||
42 | foreach ($entries as $entry) { | ||
43 | $em->persist($entry); | ||
44 | } | ||
45 | $em->flush(); | ||
46 | |||
47 | $output->writeln('<info>Done.</info>'); | ||
48 | } | ||
49 | |||
50 | /** | ||
51 | * Fetches a user from its username. | ||
52 | * | ||
53 | * @param string $username | ||
54 | * | ||
55 | * @return \Wallabag\UserBundle\Entity\User | ||
56 | */ | ||
57 | private function getUser($username) | ||
58 | { | ||
59 | return $this->getDoctrine()->getRepository('WallabagUserBundle:User')->findOneByUserName($username); | ||
60 | } | ||
61 | |||
62 | private function getDoctrine() | ||
63 | { | ||
64 | return $this->getContainer()->get('doctrine'); | ||
65 | } | ||
66 | } | ||
diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php index 5aa582f8..608ed2f0 100644 --- a/src/Wallabag/CoreBundle/Entity/Entry.php +++ b/src/Wallabag/CoreBundle/Entity/Entry.php | |||
@@ -458,6 +458,10 @@ class Entry | |||
458 | */ | 458 | */ |
459 | public function addTag(Tag $tag) | 459 | public function addTag(Tag $tag) |
460 | { | 460 | { |
461 | if ($this->tags->contains($tag)) { | ||
462 | return; | ||
463 | } | ||
464 | |||
461 | $this->tags[] = $tag; | 465 | $this->tags[] = $tag; |
462 | $tag->addEntry($this); | 466 | $tag->addEntry($this); |
463 | } | 467 | } |
diff --git a/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php b/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php index bb933779..3f9953c0 100644 --- a/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php +++ b/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php | |||
@@ -6,6 +6,7 @@ use RulerZ\RulerZ; | |||
6 | 6 | ||
7 | use Wallabag\CoreBundle\Entity\Entry; | 7 | use Wallabag\CoreBundle\Entity\Entry; |
8 | use Wallabag\CoreBundle\Entity\Tag; | 8 | use Wallabag\CoreBundle\Entity\Tag; |
9 | use Wallabag\CoreBundle\Repository\EntryRepository; | ||
9 | use Wallabag\CoreBundle\Repository\TagRepository; | 10 | use Wallabag\CoreBundle\Repository\TagRepository; |
10 | use Wallabag\UserBundle\Entity\User; | 11 | use Wallabag\UserBundle\Entity\User; |
11 | 12 | ||
@@ -13,11 +14,13 @@ class RuleBasedTagger | |||
13 | { | 14 | { |
14 | private $rulerz; | 15 | private $rulerz; |
15 | private $tagRepository; | 16 | private $tagRepository; |
17 | private $entryRepository; | ||
16 | 18 | ||
17 | public function __construct(RulerZ $rulerz, TagRepository $tagRepository) | 19 | public function __construct(RulerZ $rulerz, TagRepository $tagRepository, EntryRepository $entryRepository) |
18 | { | 20 | { |
19 | $this->rulerz = $rulerz; | 21 | $this->rulerz = $rulerz; |
20 | $this->tagRepository = $tagRepository; | 22 | $this->tagRepository = $tagRepository; |
23 | $this->entryRepository = $entryRepository; | ||
21 | } | 24 | } |
22 | 25 | ||
23 | /** | 26 | /** |
@@ -43,6 +46,35 @@ class RuleBasedTagger | |||
43 | } | 46 | } |
44 | 47 | ||
45 | /** | 48 | /** |
49 | * Apply all the tagging rules defined by a user on its entries. | ||
50 | * | ||
51 | * @param User $user | ||
52 | * | ||
53 | * @return array<Entry> A list of modified entries. | ||
54 | */ | ||
55 | public function tagAllForUser(User $user) | ||
56 | { | ||
57 | $rules = $this->getRulesForUser($user); | ||
58 | $entries = array(); | ||
59 | |||
60 | foreach ($rules as $rule) { | ||
61 | $qb = $this->entryRepository->getBuilderForAllByUser($user->getId()); | ||
62 | $entries = $this->rulerz->filter($qb, $rule->getRule()); | ||
63 | |||
64 | foreach ($entries as $entry) { | ||
65 | foreach ($rule->getTags() as $label) { | ||
66 | $tag = $this->getTag($user, $label); | ||
67 | |||
68 | $entry->addTag($tag); | ||
69 | $entries[] = $entry; | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | |||
74 | return $entries; | ||
75 | } | ||
76 | |||
77 | /** | ||
46 | * Fetch a tag for a user. | 78 | * Fetch a tag for a user. |
47 | * | 79 | * |
48 | * @param User $user | 80 | * @param User $user |
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml index 0100a62d..cef4450d 100644 --- a/src/Wallabag/CoreBundle/Resources/config/services.yml +++ b/src/Wallabag/CoreBundle/Resources/config/services.yml | |||
@@ -61,6 +61,14 @@ services: | |||
61 | arguments: | 61 | arguments: |
62 | - @rulerz | 62 | - @rulerz |
63 | - @wallabag_core.tag_repository | 63 | - @wallabag_core.tag_repository |
64 | - @wallabag_core.entry_repository | ||
65 | |||
66 | wallabag_core.entry_repository: | ||
67 | class: Wallabag\CoreBundle\Repository\EntryRepository | ||
68 | factory_service: doctrine.orm.default_entity_manager | ||
69 | factory_method: getRepository | ||
70 | arguments: | ||
71 | - WallabagCoreBundle:Entry | ||
64 | 72 | ||
65 | wallabag_core.tag_repository: | 73 | wallabag_core.tag_repository: |
66 | class: Wallabag\CoreBundle\Repository\TagRepository | 74 | class: Wallabag\CoreBundle\Repository\TagRepository |
diff --git a/src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php b/src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php index 56a1ed61..5180f7dd 100644 --- a/src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php +++ b/src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php | |||
@@ -12,15 +12,17 @@ use Wallabag\CoreBundle\Helper\RuleBasedTagger; | |||
12 | class RuleBasedTaggerTest extends \PHPUnit_Framework_TestCase | 12 | class RuleBasedTaggerTest extends \PHPUnit_Framework_TestCase |
13 | { | 13 | { |
14 | private $rulerz; | 14 | private $rulerz; |
15 | private $repository; | 15 | private $tagRepository; |
16 | private $entryRepository; | ||
16 | private $tagger; | 17 | private $tagger; |
17 | 18 | ||
18 | public function setUp() | 19 | public function setUp() |
19 | { | 20 | { |
20 | $this->rulerz = $this->getRulerZMock(); | 21 | $this->rulerz = $this->getRulerZMock(); |
21 | $this->repository = $this->getTagRepositoryMock(); | 22 | $this->tagRepository = $this->getTagRepositoryMock(); |
23 | $this->entryRepository = $this->getEntryRepositoryMock(); | ||
22 | 24 | ||
23 | $this->tagger = new RuleBasedTagger($this->rulerz, $this->repository); | 25 | $this->tagger = new RuleBasedTagger($this->rulerz, $this->tagRepository, $this->entryRepository); |
24 | } | 26 | } |
25 | 27 | ||
26 | public function testTagWithNoRule() | 28 | public function testTagWithNoRule() |
@@ -106,7 +108,7 @@ class RuleBasedTaggerTest extends \PHPUnit_Framework_TestCase | |||
106 | ->with($entry, 'rule as string') | 108 | ->with($entry, 'rule as string') |
107 | ->willReturn(true); | 109 | ->willReturn(true); |
108 | 110 | ||
109 | $this->repository | 111 | $this->tagRepository |
110 | ->expects($this->once()) | 112 | ->expects($this->once()) |
111 | ->method('findOneByLabelAndUserId') | 113 | ->method('findOneByLabelAndUserId') |
112 | ->willReturn($tag); | 114 | ->willReturn($tag); |
@@ -155,4 +157,11 @@ class RuleBasedTaggerTest extends \PHPUnit_Framework_TestCase | |||
155 | ->disableOriginalConstructor() | 157 | ->disableOriginalConstructor() |
156 | ->getMock(); | 158 | ->getMock(); |
157 | } | 159 | } |
160 | |||
161 | private function getEntryRepositoryMock() | ||
162 | { | ||
163 | return $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') | ||
164 | ->disableOriginalConstructor() | ||
165 | ->getMock(); | ||
166 | } | ||
158 | } | 167 | } |
diff --git a/src/Wallabag/UserBundle/Repository/UserRepository.php b/src/Wallabag/UserBundle/Repository/UserRepository.php index c020f3ca..009c4881 100644 --- a/src/Wallabag/UserBundle/Repository/UserRepository.php +++ b/src/Wallabag/UserBundle/Repository/UserRepository.php | |||
@@ -23,4 +23,19 @@ class UserRepository extends EntityRepository | |||
23 | ->getQuery() | 23 | ->getQuery() |
24 | ->getOneOrNullResult(); | 24 | ->getOneOrNullResult(); |
25 | } | 25 | } |
26 | |||
27 | /** | ||
28 | * Find a user by its username. | ||
29 | * | ||
30 | * @param string $username | ||
31 | * | ||
32 | * @return User | ||
33 | */ | ||
34 | public function findOneByUserName($username) | ||
35 | { | ||
36 | return $this->createQueryBuilder('u') | ||
37 | ->andWhere('u.username = :username')->setParameter('username', $username) | ||
38 | ->getQuery() | ||
39 | ->getSingleResult(); | ||
40 | } | ||
26 | } | 41 | } |