diff options
author | Jérémy Benoist <j0k3r@users.noreply.github.com> | 2017-10-23 11:09:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-23 11:09:17 +0200 |
commit | 1953a872932a63792293b4aec087880265ba89f7 (patch) | |
tree | fd16599e737fcdaf193c933ef3ec4a4ee248b117 /src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php | |
parent | d83d25dadec2c38460a32d96f5d2903426fec9d3 (diff) | |
parent | 702f2d67d60ca963492b90dad74cb5f8dcc84e51 (diff) | |
download | wallabag-1953a872932a63792293b4aec087880265ba89f7.tar.gz wallabag-1953a872932a63792293b4aec087880265ba89f7.tar.zst wallabag-1953a872932a63792293b4aec087880265ba89f7.zip |
Merge pull request #3011 from wallabag/2.3
wallabag 2.3.0
Diffstat (limited to 'src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php')
-rw-r--r-- | src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php b/src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php new file mode 100644 index 00000000..b58909db --- /dev/null +++ b/src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php | |||
@@ -0,0 +1,117 @@ | |||
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 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
11 | use Wallabag\CoreBundle\Entity\Entry; | ||
12 | use Wallabag\UserBundle\Entity\User; | ||
13 | |||
14 | class CleanDuplicatesCommand extends ContainerAwareCommand | ||
15 | { | ||
16 | /** @var SymfonyStyle */ | ||
17 | protected $io; | ||
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 | { | ||
36 | $this->io = new SymfonyStyle($input, $output); | ||
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) { | ||
45 | $this->io->error(sprintf('User "%s" not found.', $username)); | ||
46 | |||
47 | return 1; | ||
48 | } | ||
49 | |||
50 | $this->io->success('Finished cleaning.'); | ||
51 | } else { | ||
52 | $users = $this->getContainer()->get('wallabag_user.user_repository')->findAll(); | ||
53 | |||
54 | $this->io->text(sprintf('Cleaning through <info>%d</info> user accounts', count($users))); | ||
55 | |||
56 | foreach ($users as $user) { | ||
57 | $this->io->text(sprintf('Processing user <info>%s</info>', $user->getUsername())); | ||
58 | $this->cleanDuplicates($user); | ||
59 | } | ||
60 | $this->io->success(sprintf('Finished cleaning. %d duplicates found in total', $this->duplicates)); | ||
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'); | ||
72 | $repo = $this->getContainer()->get('wallabag_core.entry_repository'); | ||
73 | |||
74 | $entries = $repo->findAllEntriesIdAndUrlByUserId($user->getId()); | ||
75 | |||
76 | $duplicatesCount = 0; | ||
77 | $urls = []; | ||
78 | foreach ($entries as $entry) { | ||
79 | $url = $this->similarUrl($entry['url']); | ||
80 | |||
81 | /* @var $entry Entry */ | ||
82 | if (in_array($url, $urls, true)) { | ||
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 | |||
94 | $this->io->text(sprintf('Cleaned <info>%d</info> duplicates for user <info>%s</info>', $duplicatesCount, $user->getUserName())); | ||
95 | } | ||
96 | |||
97 | private function similarUrl($url) | ||
98 | { | ||
99 | if (in_array(substr($url, -1), ['/', '#'], true)) { // get rid of "/" and "#" and the end of urls | ||
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 | { | ||
115 | return $this->getContainer()->get('wallabag_user.user_repository')->findOneByUserName($username); | ||
116 | } | ||
117 | } | ||