From 625acf335298186b4ff983f9321900d1238e854b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Gomez?= Date: Sat, 24 Oct 2015 15:11:06 +0200 Subject: Add a command to automatically tag all entries for a user --- src/Wallabag/CoreBundle/Command/TagAllCommand.php | 66 ++++++++++++++++++++++ src/Wallabag/CoreBundle/Entity/Entry.php | 4 ++ src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php | 38 ++++++++++++- .../CoreBundle/Resources/config/services.yml | 8 +++ .../Tests/Helper/RuleBasedTaggerTest.php | 19 +++++-- .../UserBundle/Repository/UserRepository.php | 15 +++++ 6 files changed, 142 insertions(+), 8 deletions(-) create mode 100644 src/Wallabag/CoreBundle/Command/TagAllCommand.php (limited to 'src') 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 @@ +setName('wallabag:tag:all') + ->setDescription('Tag all entries using the tagging rules.') + ->addArgument( + 'username', + InputArgument::REQUIRED, + 'User to tag entries for.' + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + try { + $user = $this->getUser($input->getArgument('username')); + } catch (NoResultException $e) { + $output->writeln(sprintf('User %s not found.', $input->getArgument('username'))); + + return 1; + } + $tagger = $this->getContainer()->get('wallabag_core.rule_based_tagger'); + + $output->write(sprintf('Tagging entries for user « %s »... ', $user->getUserName())); + + $entries = $tagger->tagAllForUser($user); + + $em = $this->getDoctrine()->getManager(); + foreach ($entries as $entry) { + $em->persist($entry); + } + $em->flush(); + + $output->writeln('Done.'); + } + + /** + * Fetches a user from its username. + * + * @param string $username + * + * @return \Wallabag\UserBundle\Entity\User + */ + private function getUser($username) + { + return $this->getDoctrine()->getRepository('WallabagUserBundle:User')->findOneByUserName($username); + } + + private function getDoctrine() + { + return $this->getContainer()->get('doctrine'); + } +} 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 */ public function addTag(Tag $tag) { + if ($this->tags->contains($tag)) { + return; + } + $this->tags[] = $tag; $tag->addEntry($this); } 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; use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\Tag; +use Wallabag\CoreBundle\Repository\EntryRepository; use Wallabag\CoreBundle\Repository\TagRepository; use Wallabag\UserBundle\Entity\User; @@ -13,11 +14,13 @@ class RuleBasedTagger { private $rulerz; private $tagRepository; + private $entryRepository; - public function __construct(RulerZ $rulerz, TagRepository $tagRepository) + public function __construct(RulerZ $rulerz, TagRepository $tagRepository, EntryRepository $entryRepository) { - $this->rulerz = $rulerz; - $this->tagRepository = $tagRepository; + $this->rulerz = $rulerz; + $this->tagRepository = $tagRepository; + $this->entryRepository = $entryRepository; } /** @@ -42,6 +45,35 @@ class RuleBasedTagger } } + /** + * Apply all the tagging rules defined by a user on its entries. + * + * @param User $user + * + * @return array A list of modified entries. + */ + public function tagAllForUser(User $user) + { + $rules = $this->getRulesForUser($user); + $entries = array(); + + foreach ($rules as $rule) { + $qb = $this->entryRepository->getBuilderForAllByUser($user->getId()); + $entries = $this->rulerz->filter($qb, $rule->getRule()); + + foreach ($entries as $entry) { + foreach ($rule->getTags() as $label) { + $tag = $this->getTag($user, $label); + + $entry->addTag($tag); + $entries[] = $entry; + } + } + } + + return $entries; + } + /** * Fetch a tag for a 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: arguments: - @rulerz - @wallabag_core.tag_repository + - @wallabag_core.entry_repository + + wallabag_core.entry_repository: + class: Wallabag\CoreBundle\Repository\EntryRepository + factory_service: doctrine.orm.default_entity_manager + factory_method: getRepository + arguments: + - WallabagCoreBundle:Entry wallabag_core.tag_repository: 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; class RuleBasedTaggerTest extends \PHPUnit_Framework_TestCase { private $rulerz; - private $repository; + private $tagRepository; + private $entryRepository; private $tagger; public function setUp() { - $this->rulerz = $this->getRulerZMock(); - $this->repository = $this->getTagRepositoryMock(); + $this->rulerz = $this->getRulerZMock(); + $this->tagRepository = $this->getTagRepositoryMock(); + $this->entryRepository = $this->getEntryRepositoryMock(); - $this->tagger = new RuleBasedTagger($this->rulerz, $this->repository); + $this->tagger = new RuleBasedTagger($this->rulerz, $this->tagRepository, $this->entryRepository); } public function testTagWithNoRule() @@ -106,7 +108,7 @@ class RuleBasedTaggerTest extends \PHPUnit_Framework_TestCase ->with($entry, 'rule as string') ->willReturn(true); - $this->repository + $this->tagRepository ->expects($this->once()) ->method('findOneByLabelAndUserId') ->willReturn($tag); @@ -155,4 +157,11 @@ class RuleBasedTaggerTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); } + + private function getEntryRepositoryMock() + { + return $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + ->disableOriginalConstructor() + ->getMock(); + } } 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 ->getQuery() ->getOneOrNullResult(); } + + /** + * Find a user by its username. + * + * @param string $username + * + * @return User + */ + public function findOneByUserName($username) + { + return $this->createQueryBuilder('u') + ->andWhere('u.username = :username')->setParameter('username', $username) + ->getQuery() + ->getSingleResult(); + } } -- cgit v1.2.3