aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFrançois D <franek@users.noreply.github.com>2017-08-23 23:06:40 +0200
committerFrançois D <franek@users.noreply.github.com>2017-08-25 21:19:47 +0200
commita991c46eedec0efb24d0a9974b1c7fcabf8cfa66 (patch)
treefa33236c5ef67e023833c889eb52d5bed99d35bd
parent2490f61dca635026a3eb9b5e9b6978b1981b1172 (diff)
downloadwallabag-a991c46eedec0efb24d0a9974b1c7fcabf8cfa66.tar.gz
wallabag-a991c46eedec0efb24d0a9974b1c7fcabf8cfa66.tar.zst
wallabag-a991c46eedec0efb24d0a9974b1c7fcabf8cfa66.zip
Set a starred_at field when an entry is starred.
This date is used to sort starred entries. Can not use Entry::timestamps method otherwise starred_at will be updated each time entry is updated. Add an updateStar method into Entry class A migration script has been added in order to set starred_at field.
-rw-r--r--app/DoctrineMigrations/Version20170824113337.php63
-rw-r--r--src/Wallabag/ApiBundle/Controller/EntryRestController.php4
-rw-r--r--src/Wallabag/CoreBundle/Controller/EntryController.php1
-rw-r--r--src/Wallabag/CoreBundle/Entity/Entry.php47
-rw-r--r--src/Wallabag/CoreBundle/Repository/EntryRepository.php11
-rw-r--r--tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php5
6 files changed, 124 insertions, 7 deletions
diff --git a/app/DoctrineMigrations/Version20170824113337.php b/app/DoctrineMigrations/Version20170824113337.php
new file mode 100644
index 00000000..7393d683
--- /dev/null
+++ b/app/DoctrineMigrations/Version20170824113337.php
@@ -0,0 +1,63 @@
1<?php
2
3namespace Application\Migrations;
4
5use Doctrine\DBAL\Migrations\AbstractMigration;
6use Doctrine\DBAL\Schema\Schema;
7use Symfony\Component\DependencyInjection\ContainerAwareInterface;
8use Symfony\Component\DependencyInjection\ContainerInterface;
9
10/**
11 * Add starred_at column and set its value to updated_at for is_starred entries.
12 */
13class Version20170824113337 extends AbstractMigration implements ContainerAwareInterface
14{
15 /**
16 * @var ContainerInterface
17 */
18 private $container;
19
20 public function setContainer(ContainerInterface $container = null)
21 {
22 $this->container = $container;
23 }
24
25 /**
26 * @param Schema $schema
27 */
28 public function up(Schema $schema)
29 {
30 $entryTable = $schema->getTable($this->getTable('entry'));
31
32 $this->skipIf($entryTable->hasColumn('starred_at'), 'It seems that you already played this migration.');
33
34 $entryTable->addColumn('starred_at', 'datetime', [
35 'notnull' => false,
36 ]);
37 }
38
39 public function postUp(Schema $schema)
40 {
41 $entryTable = $schema->getTable($this->getTable('entry'));
42 $this->skipIf(!$entryTable->hasColumn('starred_at'), 'Unable to add starred_at colum');
43
44 $this->connection->executeQuery('UPDATE ' . $this->getTable('entry') . ' SET starred_at = updated_at WHERE is_starred = true');
45 }
46
47 /**
48 * @param Schema $schema
49 */
50 public function down(Schema $schema)
51 {
52 $entryTable = $schema->getTable($this->getTable('entry'));
53
54 $this->skipIf(!$entryTable->hasColumn('starred_at'), 'It seems that you already played this migration.');
55
56 $entryTable->dropColumn('starred_at');
57 }
58
59 private function getTable($tableName)
60 {
61 return $this->container->getParameter('database_table_prefix') . $tableName;
62 }
63}
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
index bc1b6f92..6db97731 100644
--- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php
+++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
@@ -361,7 +361,7 @@ class EntryRestController extends WallabagRestController
361 } 361 }
362 362
363 if (null !== $data['isStarred']) { 363 if (null !== $data['isStarred']) {
364 $entry->setStarred((bool) $data['isStarred']); 364 $entry->updateStar((bool) $data['isStarred']);
365 } 365 }
366 366
367 if (!empty($data['tags'])) { 367 if (!empty($data['tags'])) {
@@ -464,7 +464,7 @@ class EntryRestController extends WallabagRestController
464 } 464 }
465 465
466 if (null !== $data['isStarred']) { 466 if (null !== $data['isStarred']) {
467 $entry->setStarred((bool) $data['isStarred']); 467 $entry->updateStar((bool) $data['isStarred']);
468 } 468 }
469 469
470 if (!empty($data['tags'])) { 470 if (!empty($data['tags'])) {
diff --git a/src/Wallabag/CoreBundle/Controller/EntryController.php b/src/Wallabag/CoreBundle/Controller/EntryController.php
index 3dcfbebe..b0b74c38 100644
--- a/src/Wallabag/CoreBundle/Controller/EntryController.php
+++ b/src/Wallabag/CoreBundle/Controller/EntryController.php
@@ -333,6 +333,7 @@ class EntryController extends Controller
333 $this->checkUserAction($entry); 333 $this->checkUserAction($entry);
334 334
335 $entry->toggleStar(); 335 $entry->toggleStar();
336 $entry->updateStar($entry->isStarred());
336 $this->getDoctrine()->getManager()->flush(); 337 $this->getDoctrine()->getManager()->flush();
337 338
338 $message = 'flashes.entry.notice.entry_unstarred'; 339 $message = 'flashes.entry.notice.entry_unstarred';
diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php
index 61d01bdc..4367902e 100644
--- a/src/Wallabag/CoreBundle/Entity/Entry.php
+++ b/src/Wallabag/CoreBundle/Entity/Entry.php
@@ -143,6 +143,15 @@ class Entry
143 private $publishedBy; 143 private $publishedBy;
144 144
145 /** 145 /**
146 * @var \DateTime
147 *
148 * @ORM\Column(name="starred_at", type="datetime", nullable=true)
149 *
150 * @Groups({"entries_for_user", "export_all"})
151 */
152 private $starredAt = null;
153
154 /**
146 * @ORM\OneToMany(targetEntity="Wallabag\AnnotationBundle\Entity\Annotation", mappedBy="entry", cascade={"persist", "remove"}) 155 * @ORM\OneToMany(targetEntity="Wallabag\AnnotationBundle\Entity\Annotation", mappedBy="entry", cascade={"persist", "remove"})
147 * @ORM\JoinTable 156 * @ORM\JoinTable
148 * 157 *
@@ -476,6 +485,44 @@ class Entry
476 } 485 }
477 486
478 /** 487 /**
488 * @return \DateTime|null
489 */
490 public function getStarredAt()
491 {
492 return $this->starredAt;
493 }
494
495 /**
496 * @param \DateTime|null $starredAt
497 *
498 * @return Entry
499 */
500 public function setStarredAt($starredAt = null)
501 {
502 $this->starredAt = $starredAt;
503
504 return $this;
505 }
506
507 /**
508 * update isStarred and starred_at fields.
509 *
510 * @param bool $isStarred
511 *
512 * @return Entry
513 */
514 public function updateStar($isStarred = false)
515 {
516 $this->setStarred($isStarred);
517 $this->setStarredAt(null);
518 if ($this->isStarred()) {
519 $this->setStarredAt(new \DateTime());
520 }
521
522 return $this;
523 }
524
525 /**
479 * @return ArrayCollection<Annotation> 526 * @return ArrayCollection<Annotation>
480 */ 527 */
481 public function getAnnotations() 528 public function getAnnotations()
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
index eb5e3205..ecc159fc 100644
--- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
@@ -65,7 +65,7 @@ class EntryRepository extends EntityRepository
65 public function getBuilderForStarredByUser($userId) 65 public function getBuilderForStarredByUser($userId)
66 { 66 {
67 return $this 67 return $this
68 ->getBuilderByUser($userId) 68 ->getBuilderByUser($userId, 'starredAt', 'desc')
69 ->andWhere('e.isStarred = true') 69 ->andWhere('e.isStarred = true')
70 ; 70 ;
71 } 71 }
@@ -401,15 +401,16 @@ class EntryRepository extends EntityRepository
401 /** 401 /**
402 * Return a query builder to used by other getBuilderFor* method. 402 * Return a query builder to used by other getBuilderFor* method.
403 * 403 *
404 * @param int $userId 404 * @param int $userId
405 * @param string $sortBy
406 * @param string $direction
405 * 407 *
406 * @return QueryBuilder 408 * @return QueryBuilder
407 */ 409 */
408 private function getBuilderByUser($userId) 410 private function getBuilderByUser($userId, $sortBy = 'createdAt', $direction = 'desc')
409 { 411 {
410 return $this->createQueryBuilder('e') 412 return $this->createQueryBuilder('e')
411 ->andWhere('e.user = :userId')->setParameter('userId', $userId) 413 ->andWhere('e.user = :userId')->setParameter('userId', $userId)
412 ->orderBy('e.createdAt', 'desc') 414 ->orderBy(sprintf('e.%s', $sortBy), $direction);
413 ;
414 } 415 }
415} 416}
diff --git a/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php b/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php
index 2dc08be2..f4c8a630 100644
--- a/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php
+++ b/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php
@@ -407,6 +407,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
407 $this->assertSame('http://www.lemonde.fr/pixels/article/2015/03/28/plongee-dans-l-univers-d-ingress-le-jeu-de-google-aux-frontieres-du-reel_4601155_4408996.html', $content['url']); 407 $this->assertSame('http://www.lemonde.fr/pixels/article/2015/03/28/plongee-dans-l-univers-d-ingress-le-jeu-de-google-aux-frontieres-du-reel_4601155_4408996.html', $content['url']);
408 $this->assertSame(0, $content['is_archived']); 408 $this->assertSame(0, $content['is_archived']);
409 $this->assertSame(0, $content['is_starred']); 409 $this->assertSame(0, $content['is_starred']);
410 $this->assertNull($content['starred_at']);
410 $this->assertSame('New title for my article', $content['title']); 411 $this->assertSame('New title for my article', $content['title']);
411 $this->assertSame(1, $content['user_id']); 412 $this->assertSame(1, $content['user_id']);
412 $this->assertCount(2, $content['tags']); 413 $this->assertCount(2, $content['tags']);
@@ -483,6 +484,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
483 484
484 public function testPostArchivedAndStarredEntry() 485 public function testPostArchivedAndStarredEntry()
485 { 486 {
487 $now = new \DateTime();
486 $this->client->request('POST', '/api/entries.json', [ 488 $this->client->request('POST', '/api/entries.json', [
487 'url' => 'http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html', 489 'url' => 'http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html',
488 'archive' => '1', 490 'archive' => '1',
@@ -497,6 +499,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
497 $this->assertSame('http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html', $content['url']); 499 $this->assertSame('http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html', $content['url']);
498 $this->assertSame(1, $content['is_archived']); 500 $this->assertSame(1, $content['is_archived']);
499 $this->assertSame(1, $content['is_starred']); 501 $this->assertSame(1, $content['is_starred']);
502 $this->assertGreaterThanOrEqual($now->getTimestamp(), (new \DateTime($content['starred_at']))->getTimestamp());
500 $this->assertSame(1, $content['user_id']); 503 $this->assertSame(1, $content['user_id']);
501 } 504 }
502 505
@@ -753,6 +756,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
753 756
754 public function testSaveIsStarredAfterPatch() 757 public function testSaveIsStarredAfterPatch()
755 { 758 {
759 $now = new \DateTime();
756 $entry = $this->client->getContainer() 760 $entry = $this->client->getContainer()
757 ->get('doctrine.orm.entity_manager') 761 ->get('doctrine.orm.entity_manager')
758 ->getRepository('WallabagCoreBundle:Entry') 762 ->getRepository('WallabagCoreBundle:Entry')
@@ -770,6 +774,7 @@ class EntryRestControllerTest extends WallabagApiTestCase
770 $content = json_decode($this->client->getResponse()->getContent(), true); 774 $content = json_decode($this->client->getResponse()->getContent(), true);
771 775
772 $this->assertSame(1, $content['is_starred']); 776 $this->assertSame(1, $content['is_starred']);
777 $this->assertGreaterThanOrEqual($now->getTimestamp(), (new \DateTime($content['starred_at']))->getTimestamp());
773 } 778 }
774 779
775 public function dataForEntriesExistWithUrl() 780 public function dataForEntriesExistWithUrl()