From 2686457448372543fdf4f1fc54c4fd20f0f02c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Fri, 7 Aug 2015 22:20:30 +0200 Subject: store estimated reading time / filters on reading time --- .../CoreBundle/Controller/EntryController.php | 66 ++++++++++++++++++++-- .../CoreBundle/Controller/RssController.php | 17 +++++- src/Wallabag/CoreBundle/Entity/Entry.php | 4 +- src/Wallabag/CoreBundle/Filter/EntryFilterType.php | 28 +++++++++ src/Wallabag/CoreBundle/Helper/Tools.php | 12 ++++ .../CoreBundle/Repository/EntryRepository.php | 36 +++--------- .../Resources/views/Entry/entries.html.twig | 7 ++- .../Resources/views/Entry/entries.xml.twig | 4 +- .../views/themes/_global/public/css/style.css | 8 +-- .../views/themes/baggy/public/css/main.css | 50 ++++++++-------- .../views/themes/material/Entry/entries.html.twig | 5 +- .../views/themes/material/public/css/print.css | 2 +- .../Tests/Controller/EntryControllerTest.php | 19 +++++++ .../Twig/Extension/WallabagExtension.php | 13 ----- 14 files changed, 184 insertions(+), 87 deletions(-) create mode 100644 src/Wallabag/CoreBundle/Filter/EntryFilterType.php (limited to 'src/Wallabag') diff --git a/src/Wallabag/CoreBundle/Controller/EntryController.php b/src/Wallabag/CoreBundle/Controller/EntryController.php index 29e0ffb0..8894690c 100644 --- a/src/Wallabag/CoreBundle/Controller/EntryController.php +++ b/src/Wallabag/CoreBundle/Controller/EntryController.php @@ -9,6 +9,9 @@ use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Service\Extractor; use Wallabag\CoreBundle\Form\Type\NewEntryType; use Wallabag\CoreBundle\Form\Type\EditEntryType; +use Wallabag\CoreBundle\Filter\EntryFilterType; +use Pagerfanta\Adapter\DoctrineORMAdapter; +use Pagerfanta\Pagerfanta; class EntryController extends Controller { @@ -89,22 +92,39 @@ class EntryController extends Controller /** * Shows unread entries for current user. * + * @param Request $request + * @param int $page + * * @Route("/unread/list/{page}", name="unread", defaults={"page" = "1"}) * * @return \Symfony\Component\HttpFoundation\Response */ - public function showUnreadAction($page) + public function showUnreadAction(Request $request, $page) { - $entries = $this->getDoctrine() + $form = $this->get('form.factory')->create(new EntryFilterType()); + + $filterBuilder = $this->getDoctrine() ->getRepository('WallabagCoreBundle:Entry') ->findUnreadByUser($this->getUser()->getId()); + if ($request->query->has($form->getName())) { + // manually bind values from the request + $form->submit($request->query->get($form->getName())); + + // build the query from the given form object + $this->get('lexik_form_filter.query_builder_updater')->addFilterConditions($form, $filterBuilder); + } + + $pagerAdapter = new DoctrineORMAdapter($filterBuilder->getQuery()); + $entries = new Pagerfanta($pagerAdapter); + $entries->setMaxPerPage($this->getUser()->getConfig()->getItemsPerPage()); $entries->setCurrentPage($page); return $this->render( 'WallabagCoreBundle:Entry:entries.html.twig', array( + 'form' => $form->createView(), 'entries' => $entries, 'currentPage' => $page ) @@ -114,22 +134,39 @@ class EntryController extends Controller /** * Shows read entries for current user. * + * @param Request $request + * @param int $page + * * @Route("/archive/list/{page}", name="archive", defaults={"page" = "1"}) * * @return \Symfony\Component\HttpFoundation\Response */ - public function showArchiveAction($page) + public function showArchiveAction(Request $request, $page) { - $entries = $this->getDoctrine() + $form = $this->get('form.factory')->create(new EntryFilterType()); + + $filterBuilder = $this->getDoctrine() ->getRepository('WallabagCoreBundle:Entry') ->findArchiveByUser($this->getUser()->getId()); + if ($request->query->has($form->getName())) { + // manually bind values from the request + $form->submit($request->query->get($form->getName())); + + // build the query from the given form object + $this->get('lexik_form_filter.query_builder_updater')->addFilterConditions($form, $filterBuilder); + } + + $pagerAdapter = new DoctrineORMAdapter($filterBuilder->getQuery()); + $entries = new Pagerfanta($pagerAdapter); + $entries->setMaxPerPage($this->getUser()->getConfig()->getItemsPerPage()); $entries->setCurrentPage($page); return $this->render( 'WallabagCoreBundle:Entry:entries.html.twig', array( + 'form' => $form->createView(), 'entries' => $entries, 'currentPage' => $page ) @@ -139,22 +176,39 @@ class EntryController extends Controller /** * Shows starred entries for current user. * + * @param Request $request + * @param int $page + * * @Route("/starred/list/{page}", name="starred", defaults={"page" = "1"}) * * @return \Symfony\Component\HttpFoundation\Response */ - public function showStarredAction($page) + public function showStarredAction(Request $request, $page) { - $entries = $this->getDoctrine() + $form = $this->get('form.factory')->create(new EntryFilterType()); + + $filterBuilder = $this->getDoctrine() ->getRepository('WallabagCoreBundle:Entry') ->findStarredByUser($this->getUser()->getId()); + if ($request->query->has($form->getName())) { + // manually bind values from the request + $form->submit($request->query->get($form->getName())); + + // build the query from the given form object + $this->get('lexik_form_filter.query_builder_updater')->addFilterConditions($form, $filterBuilder); + } + + $pagerAdapter = new DoctrineORMAdapter($filterBuilder->getQuery()); + $entries = new Pagerfanta($pagerAdapter); + $entries->setMaxPerPage($this->getUser()->getConfig()->getItemsPerPage()); $entries->setCurrentPage($page); return $this->render( 'WallabagCoreBundle:Entry:entries.html.twig', array( + 'form' => $form->createView(), 'entries' => $entries, 'currentPage' => $page ) diff --git a/src/Wallabag/CoreBundle/Controller/RssController.php b/src/Wallabag/CoreBundle/Controller/RssController.php index 8428dce0..0558c53b 100644 --- a/src/Wallabag/CoreBundle/Controller/RssController.php +++ b/src/Wallabag/CoreBundle/Controller/RssController.php @@ -7,6 +7,8 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Wallabag\CoreBundle\Entity\User; use Wallabag\CoreBundle\Entity\Entry; +use Pagerfanta\Adapter\DoctrineORMAdapter; +use Pagerfanta\Pagerfanta; class RssController extends Controller { @@ -20,12 +22,15 @@ class RssController extends Controller */ public function showUnreadAction(User $user) { - $entries = $this->getDoctrine() + $qb = $this->getDoctrine() ->getRepository('WallabagCoreBundle:Entry') ->findUnreadByUser( $user->getId() ); + $pagerAdapter = new DoctrineORMAdapter($qb->getQuery()); + $entries = new Pagerfanta($pagerAdapter); + $perPage = $user->getConfig()->getRssLimit() ?: $this->container->getParameter('rss_limit'); $entries->setMaxPerPage($perPage); @@ -45,12 +50,15 @@ class RssController extends Controller */ public function showArchiveAction(User $user) { - $entries = $this->getDoctrine() + $qb = $this->getDoctrine() ->getRepository('WallabagCoreBundle:Entry') ->findArchiveByUser( $user->getId() ); + $pagerAdapter = new DoctrineORMAdapter($qb->getQuery()); + $entries = new Pagerfanta($pagerAdapter); + $perPage = $user->getConfig()->getRssLimit() ?: $this->container->getParameter('rss_limit'); $entries->setMaxPerPage($perPage); @@ -70,12 +78,15 @@ class RssController extends Controller */ public function showStarredAction(User $user) { - $entries = $this->getDoctrine() + $qb = $this->getDoctrine() ->getRepository('WallabagCoreBundle:Entry') ->findStarredByUser( $user->getId() ); + $pagerAdapter = new DoctrineORMAdapter($qb->getQuery()); + $entries = new Pagerfanta($pagerAdapter); + $perPage = $user->getConfig()->getRssLimit() ?: $this->container->getParameter('rss_limit'); $entries->setMaxPerPage($perPage); diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php index f139bbac..9aebc55b 100644 --- a/src/Wallabag/CoreBundle/Entity/Entry.php +++ b/src/Wallabag/CoreBundle/Entity/Entry.php @@ -7,6 +7,7 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; use Hateoas\Configuration\Annotation as Hateoas; use JMS\Serializer\Annotation\XmlRoot; +use Wallabag\CoreBundle\Helper\Tools; /** * Entry. @@ -96,7 +97,7 @@ class Entry /** * @var int * - * @ORM\Column(name="reading_type", type="integer", nullable=true) + * @ORM\Column(name="reading_time", type="integer", nullable=true) */ private $readingTime; @@ -264,6 +265,7 @@ class Entry public function setContent($content) { $this->content = $content; + $this->readingTime = Tools::getReadingTime($content); return $this; } diff --git a/src/Wallabag/CoreBundle/Filter/EntryFilterType.php b/src/Wallabag/CoreBundle/Filter/EntryFilterType.php new file mode 100644 index 00000000..636ba324 --- /dev/null +++ b/src/Wallabag/CoreBundle/Filter/EntryFilterType.php @@ -0,0 +1,28 @@ +add('readingTime', 'filter_number_range'); + } + + public function getName() + { + return 'entry_filter'; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(array( + 'csrf_protection' => false, + 'validation_groups' => array('filtering') + )); + } +} diff --git a/src/Wallabag/CoreBundle/Helper/Tools.php b/src/Wallabag/CoreBundle/Helper/Tools.php index be29ab99..d368ee71 100755 --- a/src/Wallabag/CoreBundle/Helper/Tools.php +++ b/src/Wallabag/CoreBundle/Helper/Tools.php @@ -118,4 +118,16 @@ final class Tools return str_replace('+', '', $token); } + + /** + * For a given text, we calculate reading time for an article. + * + * @param $text + * + * @return float + */ + public static function getReadingTime($text) + { + return floor(str_word_count(strip_tags($text)) / 200); + } } diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index a4514d9e..f885ee94 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php @@ -13,20 +13,15 @@ class EntryRepository extends EntityRepository * * @param int $userId * - * @return Pagerfanta + * @return QueryBuilder */ public function findUnreadByUser($userId) { - $qb = $this->createQueryBuilder('e') + return $this->createQueryBuilder('e') ->leftJoin('e.user', 'u') ->where('e.isArchived = false') ->andWhere('u.id =:userId')->setParameter('userId', $userId) - ->orderBy('e.id', 'desc') - ->getQuery(); - - $pagerAdapter = new DoctrineORMAdapter($qb); - - return new Pagerfanta($pagerAdapter); + ->orderBy('e.id', 'desc'); } /** @@ -34,21 +29,15 @@ class EntryRepository extends EntityRepository * * @param int $userId * - * @return Pagerfanta + * @return QueryBuilder */ public function findArchiveByUser($userId) { - $qb = $this->createQueryBuilder('e') - ->select('e') + return $this->createQueryBuilder('e') ->leftJoin('e.user', 'u') ->where('e.isArchived = true') ->andWhere('u.id =:userId')->setParameter('userId', $userId) - ->orderBy('e.id', 'desc') - ->getQuery(); - - $pagerAdapter = new DoctrineORMAdapter($qb); - - return new Pagerfanta($pagerAdapter); + ->orderBy('e.id', 'desc'); } /** @@ -56,22 +45,15 @@ class EntryRepository extends EntityRepository * * @param int $userId * - * @return Pagerfanta + * @return QueryBuilder */ public function findStarredByUser($userId) { - - $qb = $this->createQueryBuilder('e') - ->select('e') + return $this->createQueryBuilder('e') ->leftJoin('e.user', 'u') ->where('e.isStarred = true') ->andWhere('u.id =:userId')->setParameter('userId', $userId) - ->orderBy('e.id', 'desc') - ->getQuery(); - - $pagerAdapter = new DoctrineORMAdapter($qb); - - return new Pagerfanta($pagerAdapter); + ->orderBy('e.id', 'desc'); } /** diff --git a/src/Wallabag/CoreBundle/Resources/views/Entry/entries.html.twig b/src/Wallabag/CoreBundle/Resources/views/Entry/entries.html.twig index bf3caf09..7629ef35 100644 --- a/src/Wallabag/CoreBundle/Resources/views/Entry/entries.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/Entry/entries.html.twig @@ -21,11 +21,12 @@ {% if entries is empty %}

{% trans %}No articles found.{% endtrans %}

{% else %} +
{{ form_rest(form) }}
{% for entry in entries %} -
+

{{ entry.title|raw }}

- {% if entry.content| readingTime > 0 %} -
{% trans %}estimated reading time :{% endtrans %} {{ entry.content| readingTime }} min
+ {% if entry.readingTime > 0 %} +
{% trans %}estimated reading time :{% endtrans %} {{ entry.readingTime }} min
{% else %}
{% trans %}estimated reading time :{% endtrans %} < 1 min
{% endif %} diff --git a/src/Wallabag/CoreBundle/Resources/views/Entry/entries.xml.twig b/src/Wallabag/CoreBundle/Resources/views/Entry/entries.xml.twig index 5ec9bc03..a39a8dc3 100644 --- a/src/Wallabag/CoreBundle/Resources/views/Entry/entries.xml.twig +++ b/src/Wallabag/CoreBundle/Resources/views/Entry/entries.xml.twig @@ -17,8 +17,8 @@ {{ entry.createdAt|date('D, d M Y H:i:s') }} 0 -%} - {% trans %}estimated reading time :{% endtrans %} {{ entry.content|readingTime }} min + {%- if entry.readingTime > 0 -%} + {% trans %}estimated reading time :{% endtrans %} {{ entry.readingTime }} min {%- else -%} {% trans %}estimated reading time :{% endtrans %} < 1 min {%- endif %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/_global/public/css/style.css b/src/Wallabag/CoreBundle/Resources/views/themes/_global/public/css/style.css index e3069b86..ffd9d022 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/_global/public/css/style.css +++ b/src/Wallabag/CoreBundle/Resources/views/themes/_global/public/css/style.css @@ -121,7 +121,7 @@ a:visited { font-size: 1.3em; } -#main #content .entrie { +#main #content .entry { margin-top: 15px; padding-bottom: 15px; border-bottom: 1px dashed #222; @@ -129,19 +129,19 @@ a:visited { } /* First entry */ -#main #content .results + .entrie { +#main #content .results + .entry { clear: both; margin-top: 0; } -#main .entrie .tools { +#main .entry .tools { float: right; text-align: right; list-style-type: none; opacity: 0.5; } -#main .entrie .tools .tool span { +#main .entry .tools .tool span { display: inline-block; width: 16px; height: 16px; diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/public/css/main.css b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/public/css/main.css index e2844ccc..6090face 100755 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/public/css/main.css +++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/public/css/main.css @@ -322,7 +322,7 @@ footer a { letter-spacing:-5px; } -.listmode .entrie { +.listmode .entry { width: 100%!important; margin-left: 0!important; } @@ -343,7 +343,7 @@ footer a { top: -1px; } -.entrie { +.entry { background-color: #FFF; letter-spacing:normal; box-shadow: 0 3px 7px rgba(0,0,0,0.3); @@ -366,7 +366,7 @@ footer a { /* transition: all 0.5s ease; */ } -.entrie:before { +.entry:before { content: ""; width: 0; height: 0; @@ -384,7 +384,7 @@ footer a { transition: all 0.5s ease; } -.entrie:after { +.entry:after { content: ""; position: absolute; height: 7px; @@ -399,34 +399,34 @@ footer a { transition: all 0.5s ease; } -.entrie:hover { +.entry:hover { box-shadow: 0 3px 10px rgba(0,0,0,1); } -.entrie:hover:after { +.entry:hover:after { height: 40px; } -.entrie:hover:before { +.entry:hover:before { bottom: 2.4em; } -.entrie:hover h2 a { +.entry:hover h2 a { color: #666; } -.entrie h2 { +.entry h2 { text-transform: none; margin-bottom: 0; line-height: 1.2; } - .entrie h2:after { + .entry h2:after { content: none; } -.entrie h2 a { +.entry h2 a { display: block; text-decoration: none; color: #000; @@ -438,7 +438,7 @@ footer a { transition: all 0.5s ease; } /* -.entrie h2 a:after { +.entry h2 a:after { content: ""; position: absolute; top: 0; @@ -448,21 +448,21 @@ footer a { } */ -.entrie p { +.entry p { color: #666; font-size: 0.9em; line-height: 1.7; } - .entrie h2 a:first-letter { + .entry h2 a:first-letter { text-transform: uppercase; } -.entrie:hover .tools { +.entry:hover .tools { bottom: 0; } -.entrie .tools { +.entry .tools { position: absolute; bottom: -50px; left: 0; @@ -477,22 +477,22 @@ footer a { transition: all 0.5s ease; } - .entrie .tools a { + .entry .tools a { color: #666; text-decoration: none; display: block; padding: 0.4em; } - .entrie .tools a:hover { + .entry .tools a:hover { color: #FFF; } - .entrie .tools li { + .entry .tools li { display: inline-block; } -.entrie:nth-child(3n+1) { +.entry:nth-child(3n+1) { margin-left: 0; } @@ -941,13 +941,13 @@ pre code { ========================================================================== */ @media screen and (max-width: 1050px) { - .entrie { + .entry { width: 49%; } - .entrie:nth-child(3n+1) { + .entry:nth-child(3n+1) { margin-left: 1.5%; } - .entrie:nth-child(2n+1) { + .entry:nth-child(2n+1) { margin-left: 0; } } @@ -962,7 +962,7 @@ pre code { } @media screen and (max-width: 700px) { - .entrie { + .entry { width: 100%; margin-left: 0; } @@ -972,7 +972,7 @@ pre code { } @media screen and (max-width: 500px) { - .entrie { + .entry { width: 100%; margin-left: 0; } diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig index fbdc1ffd..b9f1be49 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig @@ -18,6 +18,7 @@ {% if entries is not empty %}
{{ entries.count }} {% trans %}entries{% endtrans %}
+
{{ form_rest(form) }}
    {% for p in range(1, entries.nbPages) %}
  • @@ -38,8 +39,8 @@
    {{ entry.title|raw }} - {% if entry.content| readingTime > 0 %} -
    {% trans %}estimated reading time: {% endtrans %} {{ entry.content| readingTime }} min
    + {% if entry.readingTime > 0 %} +
    {% trans %}estimated reading time: {% endtrans %} {{ entry.readingTime }} min
    {% else %}
    {% trans %}estimated reading time: {% endtrans %} < 1 min
    {% endif %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/public/css/print.css b/src/Wallabag/CoreBundle/Resources/views/themes/material/public/css/print.css index 9dd6d295..2a799c44 100755 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/public/css/print.css +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/public/css/print.css @@ -25,7 +25,7 @@ body > footer, div.tools, header div, .messages, -.entrie + .results { +.entry + .results { display: none !important; } diff --git a/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php index 2cd50130..24848eb2 100644 --- a/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php +++ b/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php @@ -240,4 +240,23 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertEquals(403, $client->getResponse()->getStatusCode()); } + + public function testFilterOnUnreadeView() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/unread/list'); + + $form = $crawler->filter('button[id=submit-filter]')->form(); + + $data = array( + 'entry_filter[readingTime][right_number]' => 11, + 'entry_filter[readingTime][left_number]' => 11 + ); + + $crawler = $client->submit($form, $data); + + $this->assertCount(1, $crawler->filter('div[class=entry]')); + } } diff --git a/src/Wallabag/CoreBundle/Twig/Extension/WallabagExtension.php b/src/Wallabag/CoreBundle/Twig/Extension/WallabagExtension.php index 18388948..5f0a9643 100644 --- a/src/Wallabag/CoreBundle/Twig/Extension/WallabagExtension.php +++ b/src/Wallabag/CoreBundle/Twig/Extension/WallabagExtension.php @@ -7,7 +7,6 @@ class WallabagExtension extends \Twig_Extension public function getFilters() { return array( - new \Twig_SimpleFilter('readingTime', array($this, 'getReadingTime')), new \Twig_SimpleFilter('domainName', array($this, 'getDomainName')), ); } @@ -24,18 +23,6 @@ class WallabagExtension extends \Twig_Extension return parse_url($url, PHP_URL_HOST); } - /** - * For a given text, we calculate reading time for an article. - * - * @param $text - * - * @return float - */ - public static function getReadingTime($text) - { - return floor(str_word_count(strip_tags($text)) / 200); - } - public function getName() { return 'wallabag_extension'; -- cgit v1.2.3