]>
Commit | Line | Data |
---|---|---|
e2f3800c TC |
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; | |
e1b33efb | 10 | use Symfony\Component\Console\Style\SymfonyStyle; |
e2f3800c TC |
11 | use Wallabag\CoreBundle\Entity\Entry; |
12 | use Wallabag\UserBundle\Entity\User; | |
13 | ||
14 | class CleanDuplicatesCommand extends ContainerAwareCommand | |
15 | { | |
e1b33efb NH |
16 | /** @var SymfonyStyle */ |
17 | protected $io; | |
e2f3800c TC |
18 | |
19 | protected $duplicates = 0; | |
20 | ||
21 | protected function configure() | |
22 | { | |
23 | $this | |
24 | ->setName('wallabag:clean-duplicates') | |
25 | ->setDescription('Cleans the database for duplicates') | |
26 | ->setHelp('This command helps you to clean your articles list in case of duplicates') | |
27 | ->addArgument( | |
28 | 'username', | |
29 | InputArgument::OPTIONAL, | |
30 | 'User to clean' | |
31 | ); | |
32 | } | |
33 | ||
34 | protected function execute(InputInterface $input, OutputInterface $output) | |
35 | { | |
e1b33efb | 36 | $this->io = new SymfonyStyle($input, $output); |
e2f3800c TC |
37 | |
38 | $username = $input->getArgument('username'); | |
39 | ||
40 | if ($username) { | |
41 | try { | |
42 | $user = $this->getUser($username); | |
43 | $this->cleanDuplicates($user); | |
44 | } catch (NoResultException $e) { | |
e1b33efb | 45 | $this->io->error(sprintf('User "%s" not found.', $username)); |
e2f3800c TC |
46 | |
47 | return 1; | |
48 | } | |
e1b33efb NH |
49 | |
50 | $this->io->success('Finished cleaning.'); | |
e2f3800c | 51 | } else { |
03ce43d4 | 52 | $users = $this->getContainer()->get('wallabag_user.user_repository')->findAll(); |
e2f3800c | 53 | |
e1b33efb | 54 | $this->io->text(sprintf('Cleaning through <info>%d</info> user accounts', count($users))); |
e2f3800c TC |
55 | |
56 | foreach ($users as $user) { | |
e1b33efb | 57 | $this->io->text(sprintf('Processing user <info>%s</info>', $user->getUsername())); |
e2f3800c TC |
58 | $this->cleanDuplicates($user); |
59 | } | |
e1b33efb | 60 | $this->io->success(sprintf('Finished cleaning. %d duplicates found in total', $this->duplicates)); |
e2f3800c TC |
61 | } |
62 | ||
63 | return 0; | |
64 | } | |
65 | ||
66 | /** | |
67 | * @param User $user | |
68 | */ | |
69 | private function cleanDuplicates(User $user) | |
70 | { | |
71 | $em = $this->getContainer()->get('doctrine.orm.entity_manager'); | |
03ce43d4 | 72 | $repo = $this->getContainer()->get('wallabag_core.entry_repository'); |
e2f3800c | 73 | |
dbf1188c | 74 | $entries = $repo->findAllEntriesIdAndUrlByUserId($user->getId()); |
e2f3800c TC |
75 | |
76 | $duplicatesCount = 0; | |
77 | $urls = []; | |
78 | foreach ($entries as $entry) { | |
79 | $url = $this->similarUrl($entry['url']); | |
80 | ||
81 | /* @var $entry Entry */ | |
f808b016 | 82 | if (in_array($url, $urls, true)) { |
e2f3800c TC |
83 | ++$duplicatesCount; |
84 | ||
85 | $em->remove($repo->find($entry['id'])); | |
86 | $em->flush(); // Flushing at the end of the loop would require the instance not being online | |
87 | } else { | |
88 | $urls[] = $entry['url']; | |
89 | } | |
90 | } | |
91 | ||
92 | $this->duplicates += $duplicatesCount; | |
93 | ||
e1b33efb | 94 | $this->io->text(sprintf('Cleaned <info>%d</info> duplicates for user <info>%s</info>', $duplicatesCount, $user->getUserName())); |
e2f3800c TC |
95 | } |
96 | ||
97 | private function similarUrl($url) | |
98 | { | |
f808b016 | 99 | if (in_array(substr($url, -1), ['/', '#'], true)) { // get rid of "/" and "#" and the end of urls |
e2f3800c TC |
100 | return substr($url, 0, strlen($url)); |
101 | } | |
102 | ||
103 | return $url; | |
104 | } | |
105 | ||
106 | /** | |
107 | * Fetches a user from its username. | |
108 | * | |
109 | * @param string $username | |
110 | * | |
111 | * @return \Wallabag\UserBundle\Entity\User | |
112 | */ | |
113 | private function getUser($username) | |
114 | { | |
03ce43d4 | 115 | return $this->getContainer()->get('wallabag_user.user_repository')->findOneByUserName($username); |
e2f3800c | 116 | } |
e2f3800c | 117 | } |