diff options
-rw-r--r-- | app/DoctrineMigrations/Version20190601125843.php | 54 | ||||
-rw-r--r-- | app/config/parameters.yml.dist | 2 | ||||
-rw-r--r-- | src/Wallabag/CoreBundle/Entity/Entry.php | 68 | ||||
-rw-r--r-- | src/Wallabag/CoreBundle/Helper/ContentProxy.php | 2 | ||||
-rw-r--r-- | src/Wallabag/CoreBundle/Repository/EntryRepository.php | 12 | ||||
-rw-r--r-- | tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php | 39 |
6 files changed, 165 insertions, 12 deletions
diff --git a/app/DoctrineMigrations/Version20190601125843.php b/app/DoctrineMigrations/Version20190601125843.php new file mode 100644 index 00000000..0e97606e --- /dev/null +++ b/app/DoctrineMigrations/Version20190601125843.php | |||
@@ -0,0 +1,54 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Application\Migrations; | ||
4 | |||
5 | use Doctrine\DBAL\Schema\Schema; | ||
6 | use Wallabag\CoreBundle\Doctrine\WallabagMigration; | ||
7 | |||
8 | /** | ||
9 | * Added `given_url` & `hashed_given_url` field in entry table. | ||
10 | */ | ||
11 | class Version20190601125843 extends WallabagMigration | ||
12 | { | ||
13 | /** | ||
14 | * @param Schema $schema | ||
15 | */ | ||
16 | public function up(Schema $schema) | ||
17 | { | ||
18 | $entryTable = $schema->getTable($this->getTable('entry')); | ||
19 | |||
20 | if (!$entryTable->hasColumn('given_url')) { | ||
21 | $entryTable->addColumn('given_url', 'text', [ | ||
22 | 'notnull' => false, | ||
23 | ]); | ||
24 | } | ||
25 | |||
26 | if (!$entryTable->hasColumn('hashed_given_url')) { | ||
27 | $entryTable->addColumn('hashed_given_url', 'text', [ | ||
28 | 'length' => 40, | ||
29 | 'notnull' => false, | ||
30 | ]); | ||
31 | } | ||
32 | |||
33 | // 40 = length of sha1 field hashed_given_url | ||
34 | $entryTable->addIndex(['user_id', 'hashed_given_url'], 'hashed_given_url_user_id', [], ['lengths' => [null, 40]]); | ||
35 | } | ||
36 | |||
37 | /** | ||
38 | * @param Schema $schema | ||
39 | */ | ||
40 | public function down(Schema $schema) | ||
41 | { | ||
42 | $entryTable = $schema->getTable($this->getTable('entry')); | ||
43 | |||
44 | if ($entryTable->hasColumn('given_url')) { | ||
45 | $entryTable->dropColumn('given_url'); | ||
46 | } | ||
47 | |||
48 | if ($entryTable->hasColumn('hashed_given_url')) { | ||
49 | $entryTable->dropColumn('hashed_given_url'); | ||
50 | } | ||
51 | |||
52 | $entryTable->dropIndex('hashed_given_url_user_id'); | ||
53 | } | ||
54 | } | ||
diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist index 5bd71963..9948fa46 100644 --- a/app/config/parameters.yml.dist +++ b/app/config/parameters.yml.dist | |||
@@ -36,7 +36,7 @@ parameters: | |||
36 | locale: en | 36 | locale: en |
37 | 37 | ||
38 | # A secret key that's used to generate certain security-related tokens | 38 | # A secret key that's used to generate certain security-related tokens |
39 | secret: ovmpmAWXRCabNlMgzlzFXDYmCFfzGv | 39 | secret: CHANGE_ME_TO_SOMETHING_SECRET_AND_RANDOM |
40 | 40 | ||
41 | # two factor stuff | 41 | # two factor stuff |
42 | twofactor_auth: true | 42 | twofactor_auth: true |
diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php index 8637c62f..4d5e6fc9 100644 --- a/src/Wallabag/CoreBundle/Entity/Entry.php +++ b/src/Wallabag/CoreBundle/Entity/Entry.php | |||
@@ -27,7 +27,8 @@ use Wallabag\UserBundle\Entity\User; | |||
27 | * indexes={ | 27 | * indexes={ |
28 | * @ORM\Index(name="created_at", columns={"created_at"}), | 28 | * @ORM\Index(name="created_at", columns={"created_at"}), |
29 | * @ORM\Index(name="uid", columns={"uid"}), | 29 | * @ORM\Index(name="uid", columns={"uid"}), |
30 | * @ORM\Index(name="hashed_url_user_id", columns={"user_id", "hashed_url"}, options={"lengths"={null, 40}}) | 30 | * @ORM\Index(name="hashed_url_user_id", columns={"user_id", "hashed_url"}, options={"lengths"={null, 40}}), |
31 | * @ORM\Index(name="hashed_given_url_user_id", columns={"user_id", "hashed_given_url"}, options={"lengths"={null, 40}}) | ||
31 | * } | 32 | * } |
32 | * ) | 33 | * ) |
33 | * @ORM\HasLifecycleCallbacks() | 34 | * @ORM\HasLifecycleCallbacks() |
@@ -68,6 +69,8 @@ class Entry | |||
68 | private $title; | 69 | private $title; |
69 | 70 | ||
70 | /** | 71 | /** |
72 | * Define the url fetched by wallabag (the final url after potential redirections). | ||
73 | * | ||
71 | * @var string | 74 | * @var string |
72 | * | 75 | * |
73 | * @Assert\NotBlank() | 76 | * @Assert\NotBlank() |
@@ -85,6 +88,35 @@ class Entry | |||
85 | private $hashedUrl; | 88 | private $hashedUrl; |
86 | 89 | ||
87 | /** | 90 | /** |
91 | * From where user retrieved/found the url (an other article, a twitter, or the given_url if non are provided). | ||
92 | * | ||
93 | * @var string | ||
94 | * | ||
95 | * @ORM\Column(name="origin_url", type="text", nullable=true) | ||
96 | * | ||
97 | * @Groups({"entries_for_user", "export_all"}) | ||
98 | */ | ||
99 | private $originUrl; | ||
100 | |||
101 | /** | ||
102 | * Define the url entered by the user (without redirections). | ||
103 | * | ||
104 | * @var string | ||
105 | * | ||
106 | * @ORM\Column(name="given_url", type="text", nullable=true) | ||
107 | * | ||
108 | * @Groups({"entries_for_user", "export_all"}) | ||
109 | */ | ||
110 | private $givenUrl; | ||
111 | |||
112 | /** | ||
113 | * @var string | ||
114 | * | ||
115 | * @ORM\Column(name="hashed_given_url", type="string", length=40, nullable=true) | ||
116 | */ | ||
117 | private $hashedGivenUrl; | ||
118 | |||
119 | /** | ||
88 | * @var bool | 120 | * @var bool |
89 | * | 121 | * |
90 | * @Exclude | 122 | * @Exclude |
@@ -263,15 +295,6 @@ class Entry | |||
263 | */ | 295 | */ |
264 | private $tags; | 296 | private $tags; |
265 | 297 | ||
266 | /** | ||
267 | * @var string | ||
268 | * | ||
269 | * @ORM\Column(name="origin_url", type="text", nullable=true) | ||
270 | * | ||
271 | * @Groups({"entries_for_user", "export_all"}) | ||
272 | */ | ||
273 | private $originUrl; | ||
274 | |||
275 | /* | 298 | /* |
276 | * @param User $user | 299 | * @param User $user |
277 | */ | 300 | */ |
@@ -923,6 +946,31 @@ class Entry | |||
923 | } | 946 | } |
924 | 947 | ||
925 | /** | 948 | /** |
949 | * Set given url. | ||
950 | * | ||
951 | * @param string $givenUrl | ||
952 | * | ||
953 | * @return Entry | ||
954 | */ | ||
955 | public function setGivenUrl($givenUrl) | ||
956 | { | ||
957 | $this->givenUrl = $givenUrl; | ||
958 | $this->hashedGivenUrl = UrlHasher::hashUrl($givenUrl); | ||
959 | |||
960 | return $this; | ||
961 | } | ||
962 | |||
963 | /** | ||
964 | * Get given url. | ||
965 | * | ||
966 | * @return string | ||
967 | */ | ||
968 | public function getGivenUrl() | ||
969 | { | ||
970 | return $this->givenUrl; | ||
971 | } | ||
972 | |||
973 | /** | ||
926 | * @return string | 974 | * @return string |
927 | */ | 975 | */ |
928 | public function getHashedUrl() | 976 | public function getHashedUrl() |
diff --git a/src/Wallabag/CoreBundle/Helper/ContentProxy.php b/src/Wallabag/CoreBundle/Helper/ContentProxy.php index c6fa0d98..5901df8b 100644 --- a/src/Wallabag/CoreBundle/Helper/ContentProxy.php +++ b/src/Wallabag/CoreBundle/Helper/ContentProxy.php | |||
@@ -78,6 +78,8 @@ class ContentProxy | |||
78 | $entry->setUrl($url); | 78 | $entry->setUrl($url); |
79 | } | 79 | } |
80 | 80 | ||
81 | $entry->setGivenUrl($url); | ||
82 | |||
81 | $this->stockEntry($entry, $content); | 83 | $this->stockEntry($entry, $content); |
82 | } | 84 | } |
83 | 85 | ||
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index f9cf5233..16c44885 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php | |||
@@ -366,6 +366,7 @@ class EntryRepository extends EntityRepository | |||
366 | */ | 366 | */ |
367 | public function findByHashedUrlAndUserId($hashedUrl, $userId) | 367 | public function findByHashedUrlAndUserId($hashedUrl, $userId) |
368 | { | 368 | { |
369 | // try first using hashed_url (to use the database index) | ||
369 | $res = $this->createQueryBuilder('e') | 370 | $res = $this->createQueryBuilder('e') |
370 | ->where('e.hashedUrl = :hashed_url')->setParameter('hashed_url', $hashedUrl) | 371 | ->where('e.hashedUrl = :hashed_url')->setParameter('hashed_url', $hashedUrl) |
371 | ->andWhere('e.user = :user_id')->setParameter('user_id', $userId) | 372 | ->andWhere('e.user = :user_id')->setParameter('user_id', $userId) |
@@ -376,6 +377,17 @@ class EntryRepository extends EntityRepository | |||
376 | return current($res); | 377 | return current($res); |
377 | } | 378 | } |
378 | 379 | ||
380 | // then try using hashed_given_url (to use the database index) | ||
381 | $res = $this->createQueryBuilder('e') | ||
382 | ->where('e.hashedGivenUrl = :hashed_given_url')->setParameter('hashed_given_url', $hashedUrl) | ||
383 | ->andWhere('e.user = :user_id')->setParameter('user_id', $userId) | ||
384 | ->getQuery() | ||
385 | ->getResult(); | ||
386 | |||
387 | if (\count($res)) { | ||
388 | return current($res); | ||
389 | } | ||
390 | |||
379 | return false; | 391 | return false; |
380 | } | 392 | } |
381 | 393 | ||
diff --git a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php index 9dee9891..e9c12c49 100644 --- a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php +++ b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php | |||
@@ -166,7 +166,6 @@ class EntryControllerTest extends WallabagCoreTestCase | |||
166 | $this->assertSame($this->url, $content->getUrl()); | 166 | $this->assertSame($this->url, $content->getUrl()); |
167 | $this->assertContains('Google', $content->getTitle()); | 167 | $this->assertContains('Google', $content->getTitle()); |
168 | $this->assertSame('fr', $content->getLanguage()); | 168 | $this->assertSame('fr', $content->getLanguage()); |
169 | $this->assertSame('2015-03-28 11:43:19', $content->getPublishedAt()->format('Y-m-d H:i:s')); | ||
170 | $this->assertArrayHasKey('x-frame-options', $content->getHeaders()); | 169 | $this->assertArrayHasKey('x-frame-options', $content->getHeaders()); |
171 | $client->getContainer()->get('craue_config')->set('store_article_headers', 0); | 170 | $client->getContainer()->get('craue_config')->set('store_article_headers', 0); |
172 | } | 171 | } |
@@ -269,6 +268,44 @@ class EntryControllerTest extends WallabagCoreTestCase | |||
269 | /** | 268 | /** |
270 | * This test will require an internet connection. | 269 | * This test will require an internet connection. |
271 | */ | 270 | */ |
271 | public function testPostNewOkUrlExistWithRedirection() | ||
272 | { | ||
273 | $this->logInAs('admin'); | ||
274 | $client = $this->getClient(); | ||
275 | |||
276 | $url = 'https://wllbg.org/test-redirect/c51c'; | ||
277 | |||
278 | $crawler = $client->request('GET', '/new'); | ||
279 | |||
280 | $this->assertSame(200, $client->getResponse()->getStatusCode()); | ||
281 | |||
282 | $form = $crawler->filter('form[name=entry]')->form(); | ||
283 | |||
284 | $data = [ | ||
285 | 'entry[url]' => $url, | ||
286 | ]; | ||
287 | |||
288 | $client->submit($form, $data); | ||
289 | |||
290 | $crawler = $client->request('GET', '/new'); | ||
291 | |||
292 | $this->assertSame(200, $client->getResponse()->getStatusCode()); | ||
293 | |||
294 | $form = $crawler->filter('form[name=entry]')->form(); | ||
295 | |||
296 | $data = [ | ||
297 | 'entry[url]' => $url, | ||
298 | ]; | ||
299 | |||
300 | $client->submit($form, $data); | ||
301 | |||
302 | $this->assertSame(302, $client->getResponse()->getStatusCode()); | ||
303 | $this->assertContains('/view/', $client->getResponse()->getTargetUrl()); | ||
304 | } | ||
305 | |||
306 | /** | ||
307 | * This test will require an internet connection. | ||
308 | */ | ||
272 | public function testPostNewThatWillBeTagged() | 309 | public function testPostNewThatWillBeTagged() |
273 | { | 310 | { |
274 | $this->logInAs('admin'); | 311 | $this->logInAs('admin'); |