aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--app/config/services.yml1
-rw-r--r--src/Wallabag/CoreBundle/Controller/TagController.php50
-rw-r--r--src/Wallabag/CoreBundle/Entity/Tag.php5
-rw-r--r--src/Wallabag/CoreBundle/Event/Subscriber/CustomDoctrineORMSubscriber.php38
-rw-r--r--src/Wallabag/CoreBundle/Filter/EntryFilterType.php5
-rw-r--r--src/Wallabag/CoreBundle/Form/Type/NewTagType.php30
-rw-r--r--src/Wallabag/CoreBundle/Repository/TagRepository.php17
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/Entry/entry.html.twig3
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/Tag/new_form.html.twig15
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig16
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig3
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/new_form.html.twig15
-rwxr-xr-xsrc/Wallabag/CoreBundle/Resources/views/themes/material/public/css/main.css19
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php9
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/TagControllerTest.php50
15 files changed, 258 insertions, 18 deletions
diff --git a/app/config/services.yml b/app/config/services.yml
index af22d381..b3ec7c51 100644
--- a/app/config/services.yml
+++ b/app/config/services.yml
@@ -4,6 +4,7 @@ parameters:
4 security.authentication.provider.dao.class: Wallabag\CoreBundle\Security\Authentication\Provider\WallabagAuthenticationProvider 4 security.authentication.provider.dao.class: Wallabag\CoreBundle\Security\Authentication\Provider\WallabagAuthenticationProvider
5 security.encoder.digest.class: Wallabag\CoreBundle\Security\Authentication\Encoder\WallabagPasswordEncoder 5 security.encoder.digest.class: Wallabag\CoreBundle\Security\Authentication\Encoder\WallabagPasswordEncoder
6 security.validator.user_password.class: Wallabag\CoreBundle\Security\Validator\WallabagUserPasswordValidator 6 security.validator.user_password.class: Wallabag\CoreBundle\Security\Validator\WallabagUserPasswordValidator
7 lexik_form_filter.get_filter.doctrine_orm.class: Wallabag\CoreBundle\Event\Subscriber\CustomDoctrineORMSubscriber
7 8
8services: 9services:
9 # used for tests 10 # used for tests
diff --git a/src/Wallabag/CoreBundle/Controller/TagController.php b/src/Wallabag/CoreBundle/Controller/TagController.php
index a342ec0b..fd2069e0 100644
--- a/src/Wallabag/CoreBundle/Controller/TagController.php
+++ b/src/Wallabag/CoreBundle/Controller/TagController.php
@@ -4,10 +4,60 @@ namespace Wallabag\CoreBundle\Controller;
4 4
5use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 5use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
6use Symfony\Bundle\FrameworkBundle\Controller\Controller; 6use Symfony\Bundle\FrameworkBundle\Controller\Controller;
7use Symfony\Component\HttpFoundation\Request;
8use Wallabag\CoreBundle\Form\Type\NewTagType;
9use Wallabag\CoreBundle\Entity\Tag;
10use Wallabag\CoreBundle\Entity\Entry;
7 11
8class TagController extends Controller 12class TagController extends Controller
9{ 13{
10 /** 14 /**
15 * @param Request $request
16 *
17 * @Route("/new-tag/{entry}", requirements={"entry" = "\d+"}, name="new_tag")
18 *
19 * @return \Symfony\Component\HttpFoundation\Response
20 */
21 public function addTagFormAction(Request $request, Entry $entry)
22 {
23 $tag = new Tag($this->getUser());
24 $form = $this->createForm(new NewTagType(), $tag);
25 $form->handleRequest($request);
26
27 if ($form->isValid()) {
28 $existingTag = $this->getDoctrine()
29 ->getRepository('WallabagCoreBundle:Tag')
30 ->findOneByLabelAndUserId($tag->getLabel(), $this->getUser()->getId());
31
32 $em = $this->getDoctrine()->getManager();
33
34 if (is_null($existingTag)) {
35 $entry->addTag($tag);
36 $em->persist($tag);
37 } else {
38 if (!$existingTag->hasEntry($entry)) {
39 $entry->addTag($existingTag);
40 $em->persist($existingTag);
41 }
42 }
43
44 $em->flush();
45
46 $this->get('session')->getFlashBag()->add(
47 'notice',
48 'Tag added'
49 );
50
51 return $this->redirect($this->generateUrl('view', array('id' => $entry->getId())));
52 }
53
54 return $this->render('WallabagCoreBundle:Tag:new_form.html.twig', array(
55 'form' => $form->createView(),
56 'entry' => $entry,
57 ));
58 }
59
60 /**
11 * Shows tags for current user. 61 * Shows tags for current user.
12 * 62 *
13 * @Route("/tag/list", name="tag") 63 * @Route("/tag/list", name="tag")
diff --git a/src/Wallabag/CoreBundle/Entity/Tag.php b/src/Wallabag/CoreBundle/Entity/Tag.php
index 6f005314..97c4579f 100644
--- a/src/Wallabag/CoreBundle/Entity/Tag.php
+++ b/src/Wallabag/CoreBundle/Entity/Tag.php
@@ -96,6 +96,11 @@ class Tag
96 $this->entries[] = $entry; 96 $this->entries[] = $entry;
97 } 97 }
98 98
99 public function hasEntry($entry)
100 {
101 return $this->entries->contains($entry);
102 }
103
99 /** 104 /**
100 * @return User 105 * @return User
101 */ 106 */
diff --git a/src/Wallabag/CoreBundle/Event/Subscriber/CustomDoctrineORMSubscriber.php b/src/Wallabag/CoreBundle/Event/Subscriber/CustomDoctrineORMSubscriber.php
new file mode 100644
index 00000000..cfdbfe97
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Event/Subscriber/CustomDoctrineORMSubscriber.php
@@ -0,0 +1,38 @@
1<?php
2
3namespace Wallabag\CoreBundle\Event\Subscriber;
4
5use Lexik\Bundle\FormFilterBundle\Event\Subscriber\DoctrineORMSubscriber;
6use Lexik\Bundle\FormFilterBundle\Event\GetFilterConditionEvent;
7use Symfony\Component\EventDispatcher\EventSubscriberInterface;
8
9/**
10 * This custom class override the default behavior of LexikFilterBundle on `filter_date_range`
11 * It converts a date_range to date_time_range to add hour to be able to grab a whole day (from 00:00:00 to 23:59:59).
12 */
13class CustomDoctrineORMSubscriber extends DoctrineORMSubscriber implements EventSubscriberInterface
14{
15 /**
16 * @param GetFilterConditionEvent $event
17 */
18 public function filterDateRange(GetFilterConditionEvent $event)
19 {
20 $expr = $event->getFilterQuery()->getExpressionBuilder();
21 $values = $event->getValues();
22 $value = $values['value'];
23
24 // left date should start at midnight
25 if (isset($value['left_date'][0]) && $value['left_date'][0] instanceof \DateTime) {
26 $value['left_date'][0]->setTime(0, 0, 0);
27 }
28
29 // right adte should end one second before midnight
30 if (isset($value['right_date'][0]) && $value['right_date'][0] instanceof \DateTime) {
31 $value['right_date'][0]->setTime(23, 59, 59);
32 }
33
34 if (isset($value['left_date'][0]) || isset($value['right_date'][0])) {
35 $event->setCondition($expr->dateTimeInRange($event->getField(), $value['left_date'][0], $value['right_date'][0]));
36 }
37 }
38}
diff --git a/src/Wallabag/CoreBundle/Filter/EntryFilterType.php b/src/Wallabag/CoreBundle/Filter/EntryFilterType.php
index ff51785b..85d1a061 100644
--- a/src/Wallabag/CoreBundle/Filter/EntryFilterType.php
+++ b/src/Wallabag/CoreBundle/Filter/EntryFilterType.php
@@ -27,8 +27,9 @@ class EntryFilterType extends AbstractType
27 ), 27 ),
28 'format' => 'dd/MM/yyyy', 28 'format' => 'dd/MM/yyyy',
29 'widget' => 'single_text', 29 'widget' => 'single_text',
30 ), 30 ),
31 )) 31 )
32 )
32 ->add('domainName', 'filter_text', array( 33 ->add('domainName', 'filter_text', array(
33 'apply_filter' => function (QueryInterface $filterQuery, $field, $values) { 34 'apply_filter' => function (QueryInterface $filterQuery, $field, $values) {
34 $value = $values['value']; 35 $value = $values['value'];
diff --git a/src/Wallabag/CoreBundle/Form/Type/NewTagType.php b/src/Wallabag/CoreBundle/Form/Type/NewTagType.php
new file mode 100644
index 00000000..8e4ab649
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Form/Type/NewTagType.php
@@ -0,0 +1,30 @@
1<?php
2
3namespace Wallabag\CoreBundle\Form\Type;
4
5use Symfony\Component\Form\AbstractType;
6use Symfony\Component\Form\FormBuilderInterface;
7use Symfony\Component\OptionsResolver\OptionsResolver;
8
9class NewTagType extends AbstractType
10{
11 public function buildForm(FormBuilderInterface $builder, array $options)
12 {
13 $builder
14 ->add('label', 'text', array('required' => true))
15 ->add('save', 'submit')
16 ;
17 }
18
19 public function configureOptions(OptionsResolver $resolver)
20 {
21 $resolver->setDefaults(array(
22 'data_class' => 'Wallabag\CoreBundle\Entity\Tag',
23 ));
24 }
25
26 public function getName()
27 {
28 return 'tag';
29 }
30}
diff --git a/src/Wallabag/CoreBundle/Repository/TagRepository.php b/src/Wallabag/CoreBundle/Repository/TagRepository.php
index 9c409607..ac3145a1 100644
--- a/src/Wallabag/CoreBundle/Repository/TagRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/TagRepository.php
@@ -24,4 +24,21 @@ class TagRepository extends EntityRepository
24 24
25 return new Pagerfanta($pagerAdapter); 25 return new Pagerfanta($pagerAdapter);
26 } 26 }
27
28 /**
29 * Find a tag by its label and its owner.
30 *
31 * @param string $label
32 * @param int $userId
33 *
34 * @return Tag|null
35 */
36 public function findOneByLabelAndUserId($label, $userId)
37 {
38 return $this->createQueryBuilder('t')
39 ->where('t.label = :label')->setParameter('label', $label)
40 ->andWhere('t.user = :user_id')->setParameter('user_id', $userId)
41 ->getQuery()
42 ->getOneOrNullResult();
43 }
27} 44}
diff --git a/src/Wallabag/CoreBundle/Resources/views/Entry/entry.html.twig b/src/Wallabag/CoreBundle/Resources/views/Entry/entry.html.twig
index 00480d1a..18cfd59d 100644
--- a/src/Wallabag/CoreBundle/Resources/views/Entry/entry.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/Entry/entry.html.twig
@@ -28,7 +28,8 @@
28 <h1>{{ entry.title|raw }} <a href="{{ path('edit', { 'id': entry.id }) }}" title="{% trans %}Edit tags{% endtrans %}">✎</a></h1> 28 <h1>{{ entry.title|raw }} <a href="{{ path('edit', { 'id': entry.id }) }}" title="{% trans %}Edit tags{% endtrans %}">✎</a></h1>
29 </header> 29 </header>
30 <aside class="tags"> 30 <aside class="tags">
31 tags: {% for tag in entry.tags %}<a href="./?view=tag&amp;id={{ tag.id }}">{{ tag.label }}</a> {% endfor %}<a href="./?view=edit-tags&amp;id={{ entry.id }}" title="{% trans %}Edit tags{% endtrans %}">✎</a> 31 {% for tag in entry.tags %}<span class="mdi-action-label-outline">{{ tag.label }}</span>{% endfor %}
32 {{ render(controller( "WallabagCoreBundle:Tag:addTagForm", { 'id': entry.id } )) }}
32 </aside> 33 </aside>
33 <article> 34 <article>
34 {{ entry.content | raw }} 35 {{ entry.content | raw }}
diff --git a/src/Wallabag/CoreBundle/Resources/views/Tag/new_form.html.twig b/src/Wallabag/CoreBundle/Resources/views/Tag/new_form.html.twig
new file mode 100644
index 00000000..0b5a530d
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Resources/views/Tag/new_form.html.twig
@@ -0,0 +1,15 @@
1<form name="tag" method="post" action="{{ path('new_tag', { 'entry': entry.id })}}">
2
3 {% if form_errors(form) %}
4 <span class="black-text">{{ form_errors(form) }}</span>
5 {% endif %}
6
7 {% if form_errors(form.label) %}
8 <span class="black-text">{{ form_errors(form.label) }}</span>
9 {% endif %}
10
11 {{ form_widget(form.label, { 'attr': {'autocomplete': 'off'} }) }}
12 {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'}, 'label': 'add tag' }) }}
13
14 <div class="hidden">{{ form_rest(form) }}</div>
15</form>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
index 287c5fbb..3ec31a02 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
@@ -63,13 +63,15 @@
63 <div class="row"> 63 <div class="row">
64 <div class="input-field col s12"> 64 <div class="input-field col s12">
65 <label>Rss token</label> 65 <label>Rss token</label>
66 {% if rss.token %} 66 <div>
67 {{ rss.token }} 67 {% if rss.token %}
68 {% else %} 68 {{ rss.token }}
69 <em>No token</em> 69 {% else %}
70 {% endif %} 70 <em>No token</em>
71 71 {% endif %}
72 <a href="{{ path('generate_token') }}">Regenerate ?</a> 72
73 <a href="{{ path('generate_token') }}">Regenerate ?</a>
74 </div>
73 </div> 75 </div>
74 </div> 76 </div>
75 77
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig
index b92c41b6..31b2c664 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig
@@ -137,7 +137,8 @@ main {
137 <a href="{{ entry.url|e }}" target="_blank" title="{% trans %}original{% endtrans %} : {{ entry.title|e }}" class="tool link"><span>{{ entry.domainName }}</span></a> 137 <a href="{{ entry.url|e }}" target="_blank" title="{% trans %}original{% endtrans %} : {{ entry.title|e }}" class="tool link"><span>{{ entry.domainName }}</span></a>
138 </header> 138 </header>
139 <aside class="tags"> 139 <aside class="tags">
140 tags: {% for tag in entry.tags %}<a href="./?view=tag&amp;id={{ tag.id }}">{{ tag.label }}</a> {% endfor %}<a href="./?view=edit-tags&amp;id={{ entry.id }}" title="{% trans %}Edit tags{% endtrans %}">✎</a> 140 {% for tag in entry.tags %}<span class="mdi-action-label-outline">{{ tag.label }}</span>{% endfor %}
141 {{ render(controller( "WallabagCoreBundle:Tag:addTagForm", { 'id': entry.id } )) }}
141 </aside> 142 </aside>
142 <article> 143 <article>
143 {{ entry.content | raw }} 144 {{ entry.content | raw }}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/new_form.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/new_form.html.twig
new file mode 100644
index 00000000..0b5a530d
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/new_form.html.twig
@@ -0,0 +1,15 @@
1<form name="tag" method="post" action="{{ path('new_tag', { 'entry': entry.id })}}">
2
3 {% if form_errors(form) %}
4 <span class="black-text">{{ form_errors(form) }}</span>
5 {% endif %}
6
7 {% if form_errors(form.label) %}
8 <span class="black-text">{{ form_errors(form.label) }}</span>
9 {% endif %}
10
11 {{ form_widget(form.label, { 'attr': {'autocomplete': 'off'} }) }}
12 {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'}, 'label': 'add tag' }) }}
13
14 <div class="hidden">{{ form_rest(form) }}</div>
15</form>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/public/css/main.css b/src/Wallabag/CoreBundle/Resources/views/themes/material/public/css/main.css
index 52a2be80..a976da10 100755
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/public/css/main.css
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/public/css/main.css
@@ -4,13 +4,11 @@
4 0 = Common 4 0 = Common
5 1 = Nav 5 1 = Nav
6 2 = Side-nav 6 2 = Side-nav
7 7 3 = Filters slider
8 2 = Layout 8 4 = Cards
9 3 = Pictos
10 4 = Messages
11 5 = Article 9 5 = Article
12
13 6 = Media queries 10 6 = Media queries
11 7 = Others
14 12
15 ========================================================================== */ 13 ========================================================================== */
16 14
@@ -212,7 +210,7 @@ nav input {
212} 210}
213 211
214/* ========================================================================== 212/* ==========================================================================
215 3 = Cards 213 4 = Cards
216 ========================================================================== */ 214 ========================================================================== */
217 215
218main #content { 216main #content {
@@ -261,7 +259,7 @@ main ul.row {
261} 259}
262 260
263/* ========================================================================== 261/* ==========================================================================
264 4 = Article 262 5 = Article
265 ========================================================================== */ 263 ========================================================================== */
266 264
267#article { 265#article {
@@ -365,3 +363,10 @@ main ul.row {
365 display: none; 363 display: none;
366 } 364 }
367} 365}
366/* ==========================================================================
367 7 = Others
368 ========================================================================== */
369
370div.input-field div, div.input-field ul {
371 margin-top: 40px;
372}
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php
index 5f0a6076..a0966285 100644
--- a/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php
+++ b/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php
@@ -279,6 +279,15 @@ class EntryControllerTest extends WallabagCoreTestCase
279 $this->assertCount(5, $crawler->filter('div[class=entry]')); 279 $this->assertCount(5, $crawler->filter('div[class=entry]'));
280 280
281 $data = array( 281 $data = array(
282 'entry_filter[createdAt][left_date]' => date('d/m/Y'),
283 'entry_filter[createdAt][right_date]' => date('d/m/Y'),
284 );
285
286 $crawler = $client->submit($form, $data);
287
288 $this->assertCount(5, $crawler->filter('div[class=entry]'));
289
290 $data = array(
282 'entry_filter[createdAt][left_date]' => '01/01/1970', 291 'entry_filter[createdAt][left_date]' => '01/01/1970',
283 'entry_filter[createdAt][right_date]' => '01/01/1970', 292 'entry_filter[createdAt][right_date]' => '01/01/1970',
284 ); 293 );
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/TagControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/TagControllerTest.php
index 4a43e049..af39d6ce 100644
--- a/src/Wallabag/CoreBundle/Tests/Controller/TagControllerTest.php
+++ b/src/Wallabag/CoreBundle/Tests/Controller/TagControllerTest.php
@@ -15,4 +15,54 @@ class TagControllerTest extends WallabagCoreTestCase
15 15
16 $this->assertEquals(200, $client->getResponse()->getStatusCode()); 16 $this->assertEquals(200, $client->getResponse()->getStatusCode());
17 } 17 }
18
19 public function testAddTagToEntry()
20 {
21 $this->logInAs('admin');
22 $client = $this->getClient();
23
24 $entry = $client->getContainer()
25 ->get('doctrine.orm.entity_manager')
26 ->getRepository('WallabagCoreBundle:Entry')
27 ->findOneByIsArchived(false);
28
29 $crawler = $client->request('GET', '/view/'.$entry->getId());
30
31 $form = $crawler->filter('button[id=tag_save]')->form();
32
33 $data = array(
34 'tag[label]' => 'opensource',
35 );
36
37 $client->submit($form, $data);
38 $this->assertEquals(302, $client->getResponse()->getStatusCode());
39
40 $this->assertEquals(1, count($entry->getTags()));
41
42 # tag already exists and already assigned
43 $client->submit($form, $data);
44 $this->assertEquals(302, $client->getResponse()->getStatusCode());
45
46 $newEntry = $client->getContainer()
47 ->get('doctrine.orm.entity_manager')
48 ->getRepository('WallabagCoreBundle:Entry')
49 ->findOneById($entry->getId());
50
51 $this->assertEquals(1, count($newEntry->getTags()));
52
53 # tag already exists but still not assigned to this entry
54 $data = array(
55 'tag[label]' => 'foo',
56 );
57
58 $client->submit($form, $data);
59 $this->assertEquals(302, $client->getResponse()->getStatusCode());
60
61 $newEntry = $client->getContainer()
62 ->get('doctrine.orm.entity_manager')
63 ->getRepository('WallabagCoreBundle:Entry')
64 ->findOneById($entry->getId());
65
66 $this->assertEquals(2, count($newEntry->getTags()));
67 }
18} 68}